Skip to content

fix(site): stop a missing asset from poisoning caches with HTML - #244

Merged
dvcdsys merged 1 commit into
mainfrom
claude/site-blank-page-36ceeb
Aug 13, 2026
Merged

fix(site): stop a missing asset from poisoning caches with HTML#244
dvcdsys merged 1 commit into
mainfrom
claude/site-blank-page-36ceeb

Conversation

@dvcdsys

@dvcdsys dvcdsys commented Aug 13, 2026

Copy link
Copy Markdown
Owner

The outage

codeindex.app has been serving a blank page since the 2026-08-10 deploy window (the #237#240 merges, ~22:20 UTC) — but only for people who visited during that window. The site itself is healthy: a first-time visitor today sees it fine.

Cloudflare Pages answers a request that matches no built file by serving the root index.html with a 200 (/assets/nope.js200 text/html). public/_headers stamps everything under /assets/* with max-age=31536000, immutable. During the deploy window, requests for /assets/*.js hit that combination: browsers were handed HTML pretending to be JavaScript and told to keep it, unrevalidated, until 2027. The module then fails its MIME check ("Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of text/html"), React never mounts, #root stays empty.

Measured on the live domain:

request response
fetch(url, {cache: 'force-cache'}) text/html, age: 223408 (62 h) — the poisoned entry
fetch(url, {cache: 'reload'}) application/javascript — the network is correct

A hard reload cures one browser. Nothing cures the rest, because immutable is never revalidated and the bundle filenames did not change — content hashes cannot help when the poisoned entry is keyed by a URL that was, and still is, correct.

The fix

  • public/404.html — a missing path is now a real 404, which Pages serves with Cache-Control: no-store, overriding the immutable rule. The failure can no longer be cached at all. This is the half that stops it recurring.
  • build.assetsDir: 'assets/g2' — the bundles move to /assets/g2/…, evacuating the poisoned URLs so already-affected visitors recover on their next visit: index.html is served must-revalidate and already points at the new paths.

Also gitignores .wrangler/, the state dir wrangler pages dev drops.

Verification

Ran against wrangler pages dev site/dist, which applies _headers and the real not-found behaviour:

  • /assets/g2/<missing>.js404 + Cache-Control: no-store (was 200 text/html + immutable)
  • /assets/g2/main-<hash>.js200 application/javascript + immutable — the /assets/* rule still covers the nested dir
  • landing page and /docs/ both render under the production CSP; the 404 page renders standalone (no bundle, no webfont — it has to work when the assets are the broken thing)

🤖 Generated with Claude Code

Cloudflare Pages answers a request that matches no built file by serving
the root index.html with a 200. public/_headers stamps everything under
/assets/* with `max-age=31536000, immutable`, so during the 2026-08-10
deploy window that combination handed browsers HTML pretending to be
JavaScript and told them to keep it until 2027. The module then failed
its MIME check, React never mounted, and codeindex.app has been a blank
page ever since for everyone who visited during the window — a hard
reload was the only cure, and content hashes could not help because the
poisoned entry is keyed by a URL that was, and still is, correct.

Two changes, one for each half of the problem:

- public/404.html makes a missing path a real 404. Pages serves it with
  `Cache-Control: no-store`, which overrides the immutable rule, so the
  failure can no longer be cached at all. This is the fix that stops it
  recurring.
- build.assetsDir moves the bundles to /assets/g2/, evacuating the
  poisoned URLs so already-affected visitors recover on their next
  visit: index.html is served must-revalidate and points at the new
  paths.

Verified with `wrangler pages dev site/dist`, which applies _headers and
the real not-found behaviour: /assets/g2/<missing>.js is now 404 +
no-store, the hashed bundles still get the immutable header, and both
the landing and docs pages render under the production CSP.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dvcdsys
dvcdsys merged commit 25fb4ff into main Aug 13, 2026
8 checks passed
@dvcdsys
dvcdsys deleted the claude/site-blank-page-36ceeb branch August 13, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant