fix: use no-store cache headers to prevent stale frontend chunks#12911
fix: use no-store cache headers to prevent stale frontend chunks#12911comfyanonymous merged 2 commits intomasterfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis pull request updates cache control headers in two places. In the cache middleware, the response header for JavaScript, CSS, and entry-point JSON requests is changed from "no-cache" to "no-store". In the root route handler, the Cache-Control header is changed from "no-cache" to "no-store, must-revalidate". Request routing logic and all other response handling remain unchanged. 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📝 Coding Plan
Comment |
|
This makes no sense, why would mtime and content length of the index.html be the same across versions -- assuming our http library uses etag |
After a frontend update (e.g. nightly build), browsers could load outdated cached index.html and JS/CSS chunks, causing dynamically imported modules to fail with MIME type errors and vite:preloadError. Hard refresh (Ctrl+Shift+R) was insufficient to fix the issue because Cache-Control: no-cache still allows the browser to cache and revalidate via ETags. aiohttp's FileResponse auto-generates ETags based on file mtime+size, which may not change after pip reinstall, so the browser gets 304 Not Modified and serves stale content. Clearing ALL site data in DevTools did fix it, confirming the HTTP cache was the root cause. The fix changes: - index.html: no-cache -> no-store, must-revalidate - JS/CSS/JSON entry points: no-cache -> no-store no-store instructs browsers to never cache these responses, ensuring every page load fetches the current index.html with correct chunk references. This is a small tradeoff (~5KB re-download per page load) for guaranteed correctness after updates.
8d13810 to
a9ce452
Compare
|
I don't think this actually fixes the reported issue, which may be due to some particular dev setup, but I believe it's actually still worth doing just in general. TL;DR: |
|
So this is what killed all our open workflows? When I refreshed everything was closed. |
|
This is not related to workflow persistence, it's just about an index.html file. Workflow persistence happens on browser and server storage systems. |
|
Can you open an issue describing what happened to you and the versions of ComfyUI and comfyUI frontend you are on? |
|
Sure but it's very simple. Git pulled changes. Tried to get away with using 1.41.6 (I think). Many workflows open over weeks, as you can see by when that tag was created. My API wf were fine but I wanted to use the UI. It kept complaining about powerprompt and negative prompt. Highlighted in red with nonsense error. Wouldn't let me create any more clipTextEncode nodes. They'd fall into the ether. Workflows wouldn't run. Even refreshing the page and hitting R didn't fix it.
Update to new frontend package.1.42.5. Go to refresh the page. All workflows are closed. Saved or not. Other people were complaining about this on reddit and I assume that going forward if I update the UI package, comfy will start "fresh". |
@coderabbitai can you make an issue for this |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chainSure! Let me create that issue now. 🏁 Script executed: Length of output: 49
It includes the steps to reproduce, the additional symptoms Ph0rk0z reported (red-highlighted nodes, missing |
|
Will look into this on Monday |
Problem
After updating ComfyUI locally, the browser can serve dynamically imported modules (like
dialogService) with a cached wrong MIME type (application/octet-stream), causingvite:preloadError. Hard refresh does not fix it — only clearing ALL site data resolves it.Reported in #5847, #7035, #8153, and noted in #8261 revert as needing a backend fix.
Root Cause
A transiently cached bad response gets "stuck" due to
no-cachesemantics:.jsfile with wrongContent-Type(e.g.application/octet-streamdue to Windows registryHKCR\.jsmisconfiguration affecting Pythonmimetypes.guess_type())Cache-Control: no-cacheallows the browser to store the responseIf-None-Match→ server returns304 Not Modified→ browser reuses the cached response including the original wrong Content-Typeimport()strictly enforces MIME types (unlike<script>tags which allow MIME sniffing), so the dynamic import is blockedCtrl+Shift+R) does not help because dynamic imports triggered after the Load event (e.g. user clicks "Save workflow" →promptSave()→await import(...)) use normal cache behavior, not the hard-refresh bypassThis is a rare edge case — the Windows MIME misconfiguration is not universal, and the issue only manifests when a bad response gets cached at the right time.
Fix
Change
Cache-Controlfromno-cachetono-storeforindex.html, JS, CSS, and JSON entry points.no-storeinstructs browsers to never store these responses. Withno-cache, the browser stores the response and revalidates (304 preserves stale headers). Withno-store, every request is a fresh fetch — eliminating the entire class of "stale cached headers" problems.Performance impact: none.
index.htmlis only fetched once per page load (Vue Router handles all subsequent navigation client-side). JS/CSS assets are served from localhost disk, so re-downloading ~few MB per page load is negligible.server.pyno-cache→no-store, must-revalidatefor index.htmlmiddleware/cache_middleware.pyno-cache→no-storefor .js/.css/entry point .json