sveltejs/kit · error
Hexadecimal escape sequence in ${id} must be two characters
Error message
Hexadecimal escape sequence in ${id} must be two characters What it means
A `[x+..]` hexadecimal escape in a route folder name must contain exactly two hex digits, because it decodes to a single byte via String.fromCharCode. Sequences like `[x+4]` or `[x+4142]` are rejected.
Source
Thrown at packages/kit/src/core/sync/create_manifest_data/index.js:151
/**
* @param {number} depth
* @param {string} id
* @param {string} segment
* @param {import('types').RouteData | null} parent
*/
const walk = (depth, id, segment, parent) => {
const unescaped = id.replace(/\[([ux])\+([^\]]+)\]/gi, (match, type, code) => {
if (match !== match.toLowerCase()) {
throw new Error(`Character escape sequence in ${id} must be lowercase`);
}
if (!/[0-9a-f]+/.test(code)) {
throw new Error(`Invalid character escape sequence in ${id}`);
}
if (type === 'x') {
if (code.length !== 2) {
throw new Error(`Hexadecimal escape sequence in ${id} must be two characters`);
}
return String.fromCharCode(parseInt(code, 16));
} else {
if (code.length < 4 || code.length > 6) {
throw new Error(
`Unicode escape sequence in ${id} must be between four and six characters`
);
}
return String.fromCodePoint(parseInt(code, 16));
}
});
if (/\]\[/.test(unescaped)) {
throw new Error(`Invalid route ${id} — parameters must be separated`);
}
View on GitHub (pinned to 03f1687fe6)
Solutions
- Use exactly two hex digits for [x+..], e.g. `[x+41]`
- Switch to `[u+....]` (4-6 hex digits) if you meant a Unicode codepoint like `[u+1f600]`
- Rename the folder accordingly and update links to the route
Example fix
// before // src/routes/[x+abcd]/+page.svelte // after // src/routes/[u+0041]/+page.svelte // or [x+41] for a single byte
Defensive patterns
Strategy: validation
Validate before calling
function isValidHexEscape(name) {
const m = name.match(/^\[x\+([0-9a-f]+)\]$/);
return !!m && m[1].length === 2;
}
// isValidHexEscape('[x+41]') -> true; isValidHexEscape('[x+abcd]') -> false Try / catch
try {
await build();
} catch (e) {
if (String(e.message).includes('must be two characters')) {
console.error('[x+..] needs exactly 2 hex digits, or use [u+....] for codepoints');
}
throw e;
} Prevention
- Use [x+..] only for single bytes (2 hex digits)
- Use [u+....] (4-6 digits) for Unicode codepoints
- Validate folder names with a regex in a pre-commit hook
When it happens
Trigger: Directory names such as `src/routes/[x+a]/` (one digit) or `[x+abcd]/` (four digits) — walk() throws while scanning routes at dev start or build.
Common situations: Confusing the `[x+..]` byte escape with the `[u+....]` Unicode escape that allows 4-6 digits; hand-writing escapes from memory.
Related errors
- Invalid character escape sequence in ${id}
- Character escape sequence in ${id} must be lowercase
- The "${lookup.get(key)}" and "${route.id}" routes conflict w
- Invalid export '${key}'${file ? ` in ${file}` : ''} (${hint}
- Invalid param: ${content}. Params and matcher names can only
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/23760ce42c212bee.
Report an issue: GitHub.