Build1 publisher2 min readPublished
A deploy that deletes old chunks leaves every open tab one click from a 404
React and Next.js tabs break after a release because the runtime already in the browser keeps asking for the filenames it was built with, and keeping those files served for as long as sessions live is the fix.
The Engineer · Build desk

What happened
- After a new version ships, users who already had a React or Next.js app open see ChunkLoadError or "Failed to fetch dynamically imported module", while visitors arriving fresh use the site normally.
- The runtime in the open tab still issues GET /assets/dashboard-ABC123.js, the deployment has already deleted that file, and the server answers 404 Not Found.
- The post puts the root cause as a version mismatch between the application running in the user's browser and the assets available on the server after deployment.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Cleaning the asset directory on every deploy sets the retention window to zero, so every tab still running the previous build is one navigation away from a 404 it cannot recover from.
- decision Teams have to decide where recovery lives: in release tooling that keeps old chunks answering, or in a client handler that reloads the page on a failed import.
- cost The refresh path moves the cost of a release onto the user, who has to reload an interrupted session.
Users hit the 404 when they click. Route-level splitting means the dashboard chunk is not fetched when the page loads; the browser asks for it when the user opens Dashboard [4]. A tab left open for hours can look healthy straight through a release and then break on the first navigation into a route it had not visited yet [4][13].
Two things can clear it: keep the file, or replace the runtime that asks for the file. A refresh does the second. The reload pulls version 2 HTML, the version 2 runtime and the version 2 chunks, and they match [6].
The post is blunt about what that buys. "The refresh may recover the application, but it doesn't solve the underlying deployment problem," the author wrote [7]. And on where to point the blame: "The browser isn't necessarily broken. The deployment made the asset that its current runtime needs unavailable" [8]. The piece asks whether the answer is to force every user to refresh and answers "No." [18].
This happened with hashed filenames. Version 1 shipped app-ABC123.js, dashboard-XYZ456.js and profile-111.js; version 2 shipped app-DEF789.js, dashboard-QWE321.js and profile-222.js [3]. Every filename changed between the two builds, so nothing collided [14]. Content hashes stop a browser from serving stale bytes under a fresh URL; keeping the old URL answering is a separate job. The failure came from the deployment removing dashboard-ABC123.js, after which the server returned 404 Not Found to the old runtime's request for it [5].
Decide how many previous builds stay addressable; session length sets the lower bound. In the post's scenario the user opened version 1 and the deploy landed a few hours later with the tab still open [13]. If you retain only the current build, every session older than the last release is a pending 404 [15].
Any release process that leaves the previous build's files served removes this particular error, because the error requires the old file to be gone [19]. I'd configure that before any client-side reload handler, and it is cheap: old hashed assets are immutable by construction and can expire on a timer.
The post lists its remedies as section headings, including Immutable Assets, Versioned Releases, Atomic Deployments, Rolling Deployments, Caching Strategy and What About Automatic Refresh? [11]. The supplied text breaks off mid-sentence while explaining code splitting, before those sections arrive [12]. Its diagnosis lands on the post's own formula: browser version does not equal available server assets [10].
What to watch
- Whether the full post's Immutable Assets and Versioned Releases sections prescribe a retention window in days or builds, or stop at hashed filenames.
- Release tooling defaults: whether a deploy writes into a new directory and leaves the previous build's hashed assets addressable, or swaps a directory in place.
- Whether ChunkLoadError rates in your own telemetry cluster in the minutes after a release, or spread evenly across the day.