sveltejs/kit · error · Error
Invalid param: ${content}. Params and matcher names can only
Error message
Invalid param: ${content}. Params and matcher names can only have underscores, hyphens, and alphanumeric characters. What it means
SvelteKit validates route parameter and matcher names against a regex allowing only alphanumerics, underscores, and hyphens (plus the `=`/`...` syntax). During `parse_route_id`, if a bracketed parameter segment does not match that grammar, this error is thrown at build time. In the browser the exec result is assumed non-null because the build would have already rejected invalid names.
Source
Thrown at packages/kit/src/utils/routing.js:87
if (!segment) {
return;
}
const parts = segment.split(/\[(.+?)\](?!\])/);
const result = parts
.map((content, i) => {
if (i % 2) {
if (content.startsWith('x+') || content.startsWith('u+')) {
return escape(decode_escape_sequence(content.slice(2)));
}
// We know the match cannot be null in the browser because manifest generation
// would have invoked this during build and failed if we hit an invalid
// param/matcher name with non-alphanumeric character.
const match = /** @type {RegExpExecArray} */ (param_pattern.exec(content));
if (!BROWSER && !match) {
throw new Error(
`Invalid param: ${content}. Params and matcher names can only have underscores, hyphens, and alphanumeric characters.`
);
}
const [, is_optional, is_rest, name, matcher] = match;
// It's assumed that the following invalid route id cases are already checked
// - unbalanced brackets
// - optional param following rest param
params.push({
name,
matcher,
optional: !!is_optional,
rest: !!is_rest,
chained: is_rest ? i === 1 && parts[0] === '' : false
});
return is_rest ? '([^]*?)' : is_optional ? '([^/]*)?' : '([^/]+?)';
}View on GitHub (pinned to 03f1687fe6)
Solutions
- Rename the parameter to only use letters, digits, underscores, or hyphens (e.g. `[page_id]`)
- Use `=` to separate param name from matcher name (`[id=integer]`, not `[id integer]`)
- Remove invalid characters from the matcher name and update references in the params module
Example fix
// before (route folder) src/routes/[user id=role admin]/+page.svelte // after src/routes/[user_id=role]/+page.svelte
Defensive patterns
Strategy: validation
Validate before calling
/^\/?\(?\.{0,2}\)?\/?[a-zA-Z0-9_-]+(=[a-zA-Z0-9_-]+)?\]?$/.test('[user_id=role]'); // validate folder names before creating them
const isValidParamName = (name) => /^[a-zA-Z0-9_-]+$/.test(name); Type guard
function isValidRouteParam(segment) {
const inner = segment.replace(/^[[({]|[\])}]$/g, '').replace(/^\.\.\./, '');
const [name, matcher] = inner.split('=');
return /^[a-zA-Z0-9_-]+$/.test(name) && (matcher === undefined || /^[a-zA-Z0-9_-]+$/.test(matcher));
} Prevention
- Use only letters, digits, `_`, `-` in route folder names and matcher names
- Use `=` (not a space) to separate param from matcher
- Avoid characters from other frameworks (dots, colons, spaces) in dynamic segments
When it happens
Trigger: A route file/id contains a parameter segment whose content fails `param_pattern.exec`, e.g. `[user name]`, `[id=match er]`, `[d@ta]`, or a matcher name with spaces or symbols passed to `parse_route_id` (directly or via `{ pattern }`/`{ pattern, params }` callers).
Common situations: Creating route folders with spaces or special characters like `[page id]`; mistyping a matcher separator, e.g. `[id match]` instead of `[id=match]`; copying route conventions from other frameworks that allow dots or slashes in param names.
Related errors
- Invalid character escape sequence in ${id}
- Hexadecimal escape sequence in ${id} must be two characters
- No matcher found for parameter '${name}'${file ? ` in ${file
- No matcher found for parameter '${names.values().next().valu
- Cannot build with ${JSON.stringify(file)} because Bun treats
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/2241c9726b3923e6.
Report an issue: GitHub.