sveltejs/kit · error · Error
Missing params for dynamic route ID ${id}
Error message
Missing params for dynamic route ID ${id} What it means
The $app/paths resolve() function builds URLs from route IDs. When given a route ID containing dynamic segments (e.g. /blog/[slug]) as the first argument, it requires a params object to fill those segments; without one the generated URL would be invalid, so it throws.
Source
Thrown at packages/kit/src/runtime/app/paths/client.js:73
*
* // using a route ID plus parameters
* const resolved = resolve('/blog/[slug]', {
* slug: 'hello-world'
* });
* ```
* @since 2.26
*
* @template {RouteIdWithSearchOrHash | PathnameWithSearchOrHash} T
* @param {ResolveArgs<T>} args
* @returns {ResolvedPathname}
*/
export function resolve(...args) {
const [id, params] = /** @type {[string, Record<string, string>?]} */ (args);
if (id[0] === '/') {
// route ID
if (id.includes('[') && !params) {
throw new Error(`Missing params for dynamic route ID ${id}`);
}
return (
/** @type {ResolvedPathname} */ (base + pathname_prefix + resolve_route(id, params ?? {}))
);
}
return /** @type {ResolvedPathname} */ (base + pathname_prefix + '/' + id);
}
/**
* Match a path or URL to a route ID and extracts any parameters.
*
* @example
* ```js
* import { match } from '$app/paths';
*
* const route = await match('blog/hello-world');View on GitHub (pinned to 03f1687fe6)
Solutions
- Pass a params object matching the route's dynamic segments: resolve('/blog/[slug]', { slug: 'hello' })
- For static route IDs, omit brackets or simply don't pass params (they default to {})
- Check that the ID is a real route from generated route types; use type checking so RouteId/RouteParams catch mismatches at compile time
Example fix
// before
const url = resolve('/blog/[id]');
// after
const url = resolve('/blog/[id]', { id: '42' }); Defensive patterns
Strategy: validation
Validate before calling
import { resolve } from '$app/paths';
/** @type {Record<string, string>} */
const params = { slug: 'hello' };
if (id.includes('[') && (!params || Object.keys(params).length === 0)) {
throw new Error(`resolve('${id}') requires params`);
}
const url = resolve(id, params); Type guard
/** @template {string} T */
const isDynamicRouteId = (id) => typeof id === 'string' && id.startsWith('/') && id.includes('['); Try / catch
try {
const url = resolve(routeId, params);
} catch (e) {
if (e.message.startsWith('Missing params for dynamic route ID')) {
console.error(`Provide params for ${routeId}`);
} else throw e;
} Prevention
- Always pass a params object for route IDs containing [..] segments
- Use TypeScript with generated $app/types RouteParams so missing params fail at compile time
- Prefer named route helpers or href generation from route types
- Validate params are complete before calling resolve in shared utilities
When it happens
Trigger: resolve('/blog/[slug]') — a route ID containing '[' passed with no second params argument — from client code using $app/paths.
Common situations: Forgetting to pass params for dynamic routes while using route-ID based resolution (SvelteKit 2.12+ route IDs), passing params only for some call sites, or mistakenly treating a static route pattern with brackets as a path prefix.
Related errors
- Invalid param definition
- Files prefixed with + are reserved (saw ${project_relative})
- Only Svelte files can reference named layouts. Remove '${mat
- Files and directories prefixed with + are reserved (saw ${pr
- Invalid route ID ${id}
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/a16b5e03c64eecc8.
Report an issue: GitHub.