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

  1. Pass a params object matching the route's dynamic segments: resolve('/blog/[slug]', { slug: 'hello' })
  2. For static route IDs, omit brackets or simply don't pass params (they default to {})
  3. 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

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


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/a16b5e03c64eecc8. Report an issue: GitHub.