sveltejs/kit · error · Error

Parameter '${name}' in route ${id} cannot start or end with

Error message

Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar

What it means

When substituting a string parameter into a route pattern, `resolve_route` rejects values that start or end with `/`. Embedding such values would create double or trailing slashes (like `foo//bar`), producing invalid or unintended URLs. The error identifies the offending parameter and route.

Source

Thrown at packages/kit/src/utils/routing.js:315

	return (
		'/' +
		segments
			.map((segment) =>
				segment.replace(segment_pattern, (_, escape_type, escape_code, optional, rest, name) => {
					if (escape_type) return encode_pathname_chars(decode_escape_sequence(escape_code));

					const value = params[name];

					if (value === undefined || value === '') {
						if (optional) return '';
						if (rest && value !== undefined) return '';
						throw new Error(`Missing parameter '${name}' in route ${id}`);
					}

					if (typeof value === 'string') {
						if (value.startsWith('/') || value.endsWith('/')) {
							throw new Error(
								`Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar`
							);
						}

						return value;
					}

					if (
						typeof value === 'number' ||
						typeof value === 'boolean' ||
						typeof value === 'bigint'
					) {
						return String(value);
					}

					throw new Error('Parameter values must be a string, number, boolean, or bigint');
				})
			)

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Strip leading/trailing slashes from the value before passing it (e.g. `value.replaceAll(/^\/+|\/+$/g, '')`)
  2. Use a rest parameter `[...path]` when the value legitimately spans multiple segments
  3. Validate/normalize the source of the value (config, CMS, user input) to never include boundary slashes

Example fix

// before
resolve_route(id, pattern, { path: '/settings/profile/' });
// after
resolve_route(id, pattern, { path: 'settings/profile' }); // or use [...path] route
Defensive patterns

Strategy: validation

Validate before calling

function assertNoBoundarySlashes(params) {
	for (const [k, v] of Object.entries(params)) {
		if (typeof v === 'string' && (v.startsWith('/') || v.endsWith('/'))) {
			throw new Error(`Param '${k}' must not start or end with '/': ${v}`);
		}
	}
}

Type guard

function isSafePathParam(v) {
	return typeof v !== 'string' || (v.length > 0 && !v.startsWith('/') && !v.endsWith('/'));
}

Try / catch

try {
	const href = resolveRoute(id, pattern, params);
} catch (e) {
	if (e.message.includes('cannot start or end with a slash')) {
		params = Object.fromEntries(Object.entries(params).map(([k, v]) => [k, typeof v === 'string' ? v.replace(/^\/+|\/+$/g, '') : v]));
	} else throw e;
}

Prevention

When it happens

Trigger: Calling route resolution with a param value such as `'/admin'`, `'users/'`, or `'a/b/'` for a non-rest parameter; joining path fragments into a single param instead of using rest parameters.

Common situations: Building nested paths from user/config data (e.g. `tenant.basePath` already containing a slash); passing URL-decoded values with leading slashes; misusing a regular `[path]` param where `[...path]` rest syntax is required.

Related errors


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