sveltejs/kit · error · Error
Cannot use `match(...)` inside a service worker, as it depen
Error message
Cannot use `match(...)` inside a service worker, as it depends on the SvelteKit client instance
What it means
match(...) from $app/paths relies on the running SvelteKit client instance to know the app's routes. Service workers run in a separate global scope without that client, so SvelteKit throws if match is invoked inside a ServiceWorkerGlobalScope, offering a null-returning stub otherwise.
Source
Thrown at packages/kit/src/runtime/app/paths/internal/client.js:23
/** @import { RouteId } from '$app/types' */
import { payload } from '../../../client/payload.js';
export const base = payload.base ?? __SVELTEKIT_PATHS_BASE__;
export const assets = payload.assets ?? base ?? __SVELTEKIT_PATHS_ASSETS__;
export const app_dir = __SVELTEKIT_APP_DIR__;
export const hash_routing = __SVELTEKIT_HASH_ROUTING__;
/**
* We make this configurable per-environment so that it's possible to import `$app/paths`
* into a service worker without importing the entire client
* @param {URL | string} _url
* @returns {Promise<{ [K in RouteId]: { id: K; params: import('$app/types').RouteParams<K>; } }[RouteId] | null>}
*/
// eslint-disable-next-line @typescript-eslint/require-await
export let match_implementation = async (_url) => {
// @ts-ignore
if (typeof ServiceWorkerGlobalScope !== 'undefined' && self instanceof ServiceWorkerGlobalScope) {
throw new Error(
'Cannot use `match(...)` inside a service worker, as it depends on the SvelteKit client instance'
);
}
return null;
};
/**
* @param {typeof match_implementation} fn
*/
export function set_match_implementation(fn) {
match_implementation = fn;
}
View on GitHub (pinned to 03f1687fe6)
Solutions
- In the service worker, match URLs yourself (e.g. use the route manifest passed to the sw build, or simple regex/pattern matching)
- Keep match() usage in app code only; guard shared modules so it is not called in the sw context
- Use $service-worker's `build`, `files`, and `version` exports for caching logic instead of runtime route matching
- If the sw just needs to decide which requests to handle, check request.destination/url patterns directly
Example fix
// before (service worker)
import { match } from '$app/paths';
const routes = await match(request.url);
// after
import { build, files, version } from '$service-worker';
const cached = [...build, ...files]; // decide by URL patterns instead Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof ServiceWorkerGlobalScope !== 'undefined' && self instanceof ServiceWorkerGlobalScope) {
// do NOT import/call match() here; use $service-worker exports instead
} Type guard
const inServiceWorker = () => typeof ServiceWorkerGlobalScope !== 'undefined' && self instanceof ServiceWorkerGlobalScope;
Try / catch
let routes = null;
try {
routes = await match(url);
} catch (e) {
if (e.message.includes('inside a service worker')) {
routes = matchUrlManually(url); // sw-local pattern matching
} else throw e;
} Prevention
- Never import $app/paths helpers into service worker code
- Use $service-worker (build, files, version) for sw logic
- Guard shared modules with a ServiceWorkerGlobalScope check before calling match
- Keep routing logic for sw simple (URL prefixes/patterns) rather than reusing app route resolution
When it happens
Trigger: Importing match from $app/paths (or $service-worker re-exports) and calling it inside a service worker script — detected via `self instanceof ServiceWorkerGlobalScope`.
Common situations: Writing custom service workers that try to reuse app routing helpers, copying client-side path resolution code into sw.js, or sharing a module between app and service worker that calls match at module scope.
Related errors
- Missing params for dynamic route ID ${id}
- exports is not available in dev mode
- The `generateManifest` adapter API has been removed — use `g
- Instrumentation file ${instrumentation} not found. This is p
- Entrypoint file ${entrypoint} not found. This is probably a
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/e87239f41bf7c239.
Report an issue: GitHub.