GraphiteEditor/Graphite · error
Precache fetch failed for ${entry.url}: ${response.status}
Error message
Precache fetch failed for ${entry.url}: ${response.status} What it means
During service-worker install, every URL in PRECACHE_MANIFEST (JS, Wasm, index.html, favicons — placeholders injected by vite.config.ts at build time) is fetched; any non-ok response aborts the Promise.all, which rejects event.waitUntil and fails installation. The new service worker never activates, so clients stay on the previous version or end up with no worker at all.
Source
Thrown at frontend/src/service-worker.js:62
const cached = await cache.match(request);
if (cached) return cached;
throw new Error(`Network request failed and no cache available for ${request.url}`);
}
}
// ================
// Lifecycle events
// ================
self.addEventListener("install", (event) => {
event.waitUntil(
(async () => {
// Precache app shell assets
const cache = await caches.open(STATIC_CACHE_NAME);
await Promise.all(
PRECACHE_MANIFEST.map(async (entry) => {
const response = await fetch(entry.url);
if (!response.ok) throw new Error(`Precache fetch failed for ${entry.url}: ${response.status}`);
// Strip the `redirected` flag which causes errors when served via respondWith
const cleaned = response.redirected
? new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: response.headers,
})
: response;
await cache.put(entry.url, cleaned);
}),
);
// Proactively cache the font catalog API
try {
const fontResponse = await fetch(FONT_LIST_API);
if (fontResponse.ok) {
const fontCache = await caches.open(RUNTIME_FONTS);
await fontCache.put(FONT_LIST_API, fontResponse);View on GitHub (pinned to c507b35645)
Solutions
- Open the failing entry.url from the error message in a browser or curl and confirm the status — this pinpoints the missing asset
- Rebuild and redeploy so PRECACHE_MANIFEST is generated from the exact asset set that ships (every hashed file present on the server)
- If clients hold a stale manifest, bumping SERVICE_WORKER_CONTENT_HASH via a fresh deploy gives them a consistent worker+assets pair
- Fetch with { cache: "reload" } and/or retry transient failures once during install instead of failing the entire install
Example fix
// before
const response = await fetch(entry.url);
if (!response.ok) throw new Error(`Precache fetch failed for ${entry.url}: ${response.status}`);
// after: bypass stale HTTP cache and retry transient failures once
async function fetchEntry(url) {
for (let attempt = 0; attempt < 2; attempt += 1) {
try {
const r = await fetch(url, { cache: "reload" });
if (r.ok) return r;
} catch { /* retry */ }
}
return fetch(url, { cache: "reload" });
}
const response = await fetchEntry(entry.url);
if (!response.ok) throw new Error(`Precache fetch failed for ${entry.url}: ${response.status}`); Defensive patterns
Strategy: retry
Validate before calling
// Pre-deploy smoke check: every precache URL must return 200
import { readFileSync } from "node:fs";
const manifest = JSON.parse(readFileSync("dist/sw-manifest.json", "utf8"));
for (const { url } of manifest) {
const res = await fetch(new URL(url, base).href);
if (!res.ok) throw new Error(`Missing precache asset: ${url} (${res.status})`);
} Try / catch
// Per-entry catch that logs the entry, then rethrows so install still fails loudly
PRECACHE_MANIFEST.map(async (entry) => {
try { /* fetch + cache.put */ } catch (e) {
console.error(`Precache failed for ${entry.url}`, e);
throw e;
}
}); Prevention
- Generate the precache manifest in the same build step that emits the hashed assets
- Upload dist/ atomically (all files or nothing) so the worker never sees a half-deployed manifest
- Add a CI Playwright/Puppeteer step that registers the service worker and waits for a clean install
- Use { cache: "reload" } on install-time fetches to bypass stale HTTP cache entries
When it happens
Trigger: A manifest entry returns 404 — typically a hashed asset name from a build whose files were not all deployed; a host returning 401/403 for an asset; an HTTP-cached stale 404 for a previously missing file; index.html reached through a redirect chain that ends in an error status.
Common situations: Partial deploys where some dist/ artifacts (especially hashed files like the split -partN.wasm chunks referenced by the manifest) were not uploaded; serving from a subpath or wrong scope so relative manifest URLs resolve incorrectly; a CDN purge mid-deploy; stale browser HTTP cache during a service-worker update.
Related errors
- Failed to fetch Wasm binary part (status ${failedResponse.st
- Network request failed and no cache available for ${request.
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/3221535dd2349b63.
Report an issue: GitHub.