DEV Community

Cover image for The Angular Error That Kept Scratching My Head: NG02100
Avinash Dalvi for This is Angular

Posted on • Originally published at internetkatta.com

The Angular Error That Kept Scratching My Head: NG02100

Hello Devs,

You know those moments where everything compiles, no warnings pop up, the UI mostly works… but then something just quietly breaks?

This was one of those moments.

I wasn’t refactoring some ancient service or tweaking a low-level renderer. I was building a simple notification drawer — and somehow, Angular's NG02100 error made it feel like the app was haunted.

When “Just a Template Change” Isn’t

I was working on our notification drawer — a simple list showing who did what, when. The API was returning the usual data: message, title, timestamp. Nothing out of the ordinary.

In the template, I rendered the notification time like this:

<label class="notification-time"> {{ notification?.cd | date: 'MMM d, y h:mm a' }} </label> 
Enter fullscreen mode Exit fullscreen mode

It worked. I merged it. Life moved on.

Until it didn’t.

The Crash That Made No Sense

One morning, I refreshed the UI. The first few notifications loaded. Then — out of nowhere — Angular crashed.

it worked yesterday

Sometimes it broke after the third item, sometimes after the fifth. It wasn’t consistent. But the crash was real, and the console wasn’t much help:

 ERROR $e: NG02100 at qn (http://localhost:4200/main.js:1:1782481) at Me.transform (http://localhost:4200/main.js:1:1784244) at H2 (http://localhost:4200/main.js:1:1923346) at Object.Y2 (http://localhost:4200/main.js:1:1924135) at pp (http://localhost:4200/main.js:1:556184) at L0 (http://localhost:4200/main.js:1:1865117) at ZC (http://localhost:4200/main.js:1:1875545) at X0 (http://localhost:4200/main.js:1:1876956) at Hb (http://localhost:4200/main.js:1:1876779) at Jm (http://localhost:4200/main.js:1:1876711) 
Enter fullscreen mode Exit fullscreen mode

No mention of the template line. No stack trace pointing to my component. Just NG02100.

I hadn’t seen this one before. And I write a lot of Angular.

Debugging the Wrong Places

Like most devs, I assumed something logical was broken. So I started removing things.

I tried:

  • Wrapping fields in *ngIf

  • Adding ?. everywhere

  • Logging the API response

  • Filtering out null and incomplete records

  • Removing pipes, anchor tags, images, even entire rows

At one point I replaced the whole template with just:

{{ notification | json }} 
Enter fullscreen mode Exit fullscreen mode

Still crashing.

The error pointed to the line in my component where I assigned the response:

this.notifications = res.data; 
Enter fullscreen mode Exit fullscreen mode

And yet the first few notifications rendered fine. That made it worse — it felt like the problem was hiding somewhere deep in the data, waiting to ambush me at random.

The Breakthrough

After hours of slicing code, I dumped a single notification to the console and noticed this:

cd": "9 mins ago" 
Enter fullscreen mode Exit fullscreen mode

That used to be:

"cd": "2024-06-06T12:30:00Z" 
Enter fullscreen mode Exit fullscreen mode

So what changed?

The backend team had switched from sending ISO timestamps to human-readable time strings.

Totally reasonable — but my date pipe didn’t agree.

Angular was trying to parse "9 mins ago" with the date pipe. Naturally, it failed. But instead of throwing a descriptive error, it threw NG02100, which just means:

Something in the template broke during binding. Good luck finding it.

The Fix Was Simple (But Finding It Wasn't)

I removed the date pipe entirely:

<label class="notification-time"> {{ notification?.cd }} </label> 
Enter fullscreen mode Exit fullscreen mode

Just like that — everything worked again.

It took two hours to track down a single pipe that was assuming a valid date. A change that didn't cause TypeScript to fail. A runtime-only issue that crashed without context.

Finally worked

Lessons from the Trap

Looking back, this one line taught me more than I expected:

  1. NG02100 is a template binding failure, not a logic error.

  2. Pipes like date, currency, or async are easy to break if the data isn’t shaped exactly as expected.

  3. When errors seem random in a loop (*ngFor), it’s usually one bad record in the list.

  4. Defensive programming in templates is just as important as in your components.

What I’d Do Differently Now

  • Validate data types before using them in the template.

  • Guard pipes behind helper functions if the format can vary.

  • Use conditional formatting:

  • And finally, when I see NG02100 again, I’ll know where to look first — the template, not the logic

Final Thoughts

This wasn’t a tricky bug in hindsight. But it was just invisible enough, just misleading enough, to waste hours of time.

Sometimes the problem isn’t what changed — it’s what you assumed would never change.

If you ever see NG02100, don’t start with your TypeScript.

Start with your templates.

And then check your pipes.

Top comments (2)

Collapse
 
dzhavat profile image
Dzhavat Ushev This is Angular

If the backend started sending human-readable strings to the front-end instead of ISO timestamps overnight, I'd consider that a breaking change. They shouldn't be allowed to do that without telling you.
Thanks for sharing your experience.

Collapse
 
avinashdalvi_ profile image
Avinash Dalvi This is Angular

This is just case but main learning is whenever you see this error code is always template binding errrot