GraphiteEditor/Graphite · error

Network request failed and no cache available for ${request.

Error message

Network request failed and no cache available for ${request.url}

What it means

Thrown by the Graphite service worker's networkFirst strategy, which is used only for the font catalog API (https://api.graphite.art/font-list). It fires when the live fetch() rejects (offline, DNS failure, API unreachable) AND the runtime-fonts cache holds no previously stored response for that URL. The rejection propagates out of event.respondWith, so the page sees a failed request for the font list.

Source

Thrown at frontend/src/service-worker.js:46

	const cache = await caches.open(cacheName);
	const cached = await cache.match(request);
	if (cached) return cached;

	const response = await fetch(request);
	if (isCacheable(response)) cache.put(request, response.clone());
	return response;
}

async function networkFirst(request, cacheName) {
	const cache = await caches.open(cacheName);
	try {
		const response = await fetch(request);
		if (isCacheable(response)) cache.put(request, response.clone());
		return response;
	} catch {
		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

View on GitHub (pinned to c507b35645)

Solutions

  1. Bring the browser online and load the font list once so networkFirst caches a good response, then retest offline
  2. Catch the rejection in the fetch handler and return a 503 Response with an empty font list instead of letting it fail
  3. Verify the cache name passed to networkFirst (RUNTIME_FONTS) matches the cache the install-time prefetch writes to
  4. Check that a proxy, extension, or DNS issue is not blocking api.graphite.art

Example fix

// before (service-worker.js networkFirst)
} catch {
	const cached = await cache.match(request);
	if (cached) return cached;
	throw new Error(`Network request failed and no cache available for ${request.url}`);
}

// after: degrade gracefully instead of throwing
} catch {
	const cached = await cache.match(request);
	if (cached) return cached;
	return new Response("{\"fonts\":[]}", { status: 503, headers: { "Content-Type": "application/json" } });
}
Defensive patterns

Strategy: fallback

Validate before calling

// Check whether the font catalog is cached before relying on it offline
async function fontListCached(): Promise<boolean> {
	const cache = await caches.open("runtime-fonts");
	return Boolean(await cache.match("https://api.graphite.art/font-list"));
}

Try / catch

// In the SW fetch handler, catch the networkFirst rejection and degrade gracefully
event.respondWith(
	networkFirst(request, RUNTIME_FONTS).catch(
		() => new Response("{\"fonts\":[]}", { status: 503, headers: { "Content-Type": "application/json" } }),
	),
);

Prevention

When it happens

Trigger: DevTools offline throttling or a genuinely offline machine combined with a font list that was never cached: the install-time prefetch of FONT_LIST_API is best-effort (wrapped in try/catch, only cached when response.ok), so a failed first fetch leaves the runtime-fonts cache empty and every later offline request hits this throw.

Common situations: Testing the PWA offline right after a fresh install where the font catalog prefetch failed; api.graphite.art blocked by an extension, firewall, or corporate proxy; a first response that was 4xx/5xx (isCacheable() refuses to store non-ok, non-opaque responses, so no offline fallback ever gets seeded).

Related errors


AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16). Data as JSON: /api/errors/95f8a39389452001. Report an issue: GitHub.