Back to News & Insights
Web Development September 8, 2026 · 4 min read

"Application error: a client-side exception has occurred" Is a Stale Chunk 404

I run AI Change Watch, a small independent project that crawls what 15 AI vendors publish about their...

"Application error: a client-side exception has occurred" Is a Stale Chunk 404

I run AI Change Watch, a small independent project that crawls what 15 AI vendors publish about their own models — deprecation tables, lifecycle pages, pricing and SDK releases — and records every time one of them changes. It's Next.js App Router on Cloudflare Workers via OpenNext.

For a while it would, occasionally, break in the browser after I shipped something. Not on load — on the next click.

You have the site open. You navigate — Home, a provider page, anything with a client transition. Instead of the page you get a white screen and one line:

Two properties make this genuinely hard to place: It's intermittent. It hits some tabs and not others, some navigations and not others. The message is deliberately empty. That string is React's production error boundary refusing to leak details. It is the same message for every uncaught render error, so it tells you nothing about which one you have.

Every request. And Home returned 200 across every filter, every provider, every page size I tried. No 500, no thrown exception, no failed render.

That reads as "the server is healthy, so the bug is in my component code" — and it sends you into the one place the problem is not. It took me longer than it should have to state the actual reason the logs were empty:

Worker logs never contain client exceptions. The error happened in the browser, after the response was delivered and logged as a success. A clean server log is not evidence about the client. It's silence about the client.

Open DevTools, keep the Network tab open, and reproduce the navigation. You are looking for a 404 on a /_next/static/... path:

If it's there, you are done diagnosing. That is deployment skew, and the underlying error is a ChunkLoadError — React caught it, and the boundary printed the generic line.

You can confirm it in the Console, which will have the real message that the page refused to show you:

Next.js splits your app into hashed chunks and loads them on demand. A page you open is not the whole app — it's an HTML document plus the chunks needed so far. The chunks for a route you haven't visited yet are fetched at the moment you navigate there.

The hash in a chunk's filename is derived from its contents. Change layout.tsx and layout-4f2c9a1b8e.js becomes layout-91d0c73aa2.js.

Now put those two facts together with how static assets are hosted. On Workers Assets — and on most static hosting, this is not Cloudflare-specific — only the current build's assets exist. Deploying replaces the set. The old hashed filenames stop resolving.

So the sequence is: A browser loads the site on build A. The document and the initial chunks are A's. You deploy build B. A's chunk files are gone. That still-open tab navigates. It requests the chunk name it learned from A. 404. ChunkLoadError. Generic error boundary.

Which explains both properties from the top. Intermittent, because it only affects tabs that were loaded before the deploy and then navigated after it. Fixed by reload, because a reload fetches the new document, which references B's chunk names.

It also explains why this feels like it's getting worse when you're actively working: during a session where you deploy six times in an hour, every tab you left open is a candidate. At a normal release cadence it only touches people who happened to have the site open across the deploy.

Recover automatically. Add an error boundary that recognises this specific failure and reloads instead of rendering the message:

This is the honest fix for a user-facing site: the reload is what the visitor would have done anyway, so do it for them. The cost is that you have taken a class of error and made it invisible — if something else ever produces a ChunkLoadError, you now have a silent reload loop instead of a report.

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation