sveltejs/kit · warning
'${id}' has no `+page`, so there is no code to preload. If y
Error message
'${id}' has no `+page`, so there is no code to preload. If you meant to warm up an endpoint, request it with `fetch` instead. What it means
`preloadData()`/`preloadCode()` take route IDs, not URL pathnames. If the given ID resolves to an endpoint-only route (no `+page` file), there is no client code to preload, so SvelteKit warns and returns without loading anything, suggesting `fetch` for warming up endpoints.
Source
Thrown at packages/kit/src/runtime/client/client.js:2869
* Returns a Promise that resolves when the modules have been imported.
*
* @param {import('$app/types').RouteId} id
* @returns {Promise<void>}
*/
export async function preloadCode(id) {
if (DEV && id[0] !== '/') {
throw new Error(
`argument passed to preloadCode must be a route ID (i.e. "/blog/[slug]" rather than "blog/[slug]")`
);
}
const route = __SVELTEKIT_CLIENT_ROUTING__
? routes.find((r) => r.id === id)
: (route_id_cache.get(id) ?? (await load_route_by_id(id)));
if (route === ENDPOINT_ONLY) {
if (DEV) {
console.warn(
`'${id}' has no \`+page\`, so there is no code to preload. If you meant to warm up an ` +
`endpoint, request it with \`fetch\` instead.`
);
}
return;
}
if (!route) {
if (DEV) {
// warn rather than throw, since under client routing an endpoint-only route id is
// indistinguishable from a typo — the client manifest only contains routes with a `+page`
let message = `'${id}' did not match any route`;
if (__SVELTEKIT_CLIENT_ROUTING__) {
message += ` (note that routes without a \`+page\` have no code to preload)`;
// the most common migration mistake is passing a pathname, which used to workView on GitHub (pinned to 03f1687fe6)
Solutions
- Use `fetch('/api/...')` to warm up endpoint-only routes instead of preloadData/preloadCode
- Only preload route IDs that have a `+page` component
- Add a route with a `+page` file if client-side preloading is actually desired
Example fix
// before
await preloadData('/api/data');
// after
await fetch('/api/data'); Defensive patterns
Strategy: validation
Validate before calling
// only preload routes that have a +page
const isEndpointOnly = (id) => id.includes('+server') && !id.includes('+page');
if (isEndpointOnly(id)) { await fetch(resolveRoute(id)); } else { await preloadData(id); } Type guard
function hasPage(id) { return typeof id === 'string' && id.includes('+page'); } Prevention
- Remember preload targets client code, not endpoints — use fetch for APIs
- Route IDs include node files like `/x/+page@svelte`, not bare pathnames
When it happens
Trigger: Calling `preloadData('/api/...')` or `preloadCode()` with the ID of a `+server.js`-only route in DEV; the resolver in packages/kit/src/runtime/client/client.js finds the route, sees `route === ENDPOINT_ONLY`, and warns.
Common situations: Preloading API endpoints by mistake assuming preload performs a request; passing pathname strings instead of route IDs after refactoring routes.
Related errors
- '${id}' did not match any route (note that routes without a
- Avoid using `history.pushState(...)` and `history.replaceSta
- Cannot build with ${JSON.stringify(file)} because Bun treats
- Cannot build with ${JSON.stringify(file)} because Bun treats
- Page options are ignored when `router.type === 'hash'` (${no
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/fd583b5d45204516.
Report an issue: GitHub.