{"record":{"id":"23760ce42c212bee","repo":"sveltejs/kit","slug":"hexadecimal-escape-sequence-in-id-must-be-two-c","errorCode":null,"errorMessage":"Hexadecimal escape sequence in ${id} must be two characters","messagePattern":"Hexadecimal escape sequence in (.+?) must be two characters","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/kit/src/core/sync/create_manifest_data/index.js","lineNumber":151,"sourceCode":"\t\t/**\n\t\t * @param {number} depth\n\t\t * @param {string} id\n\t\t * @param {string} segment\n\t\t * @param {import('types').RouteData | null} parent\n\t\t */\n\t\tconst walk = (depth, id, segment, parent) => {\n\t\t\tconst unescaped = id.replace(/\\[([ux])\\+([^\\]]+)\\]/gi, (match, type, code) => {\n\t\t\t\tif (match !== match.toLowerCase()) {\n\t\t\t\t\tthrow new Error(`Character escape sequence in ${id} must be lowercase`);\n\t\t\t\t}\n\n\t\t\t\tif (!/[0-9a-f]+/.test(code)) {\n\t\t\t\t\tthrow new Error(`Invalid character escape sequence in ${id}`);\n\t\t\t\t}\n\n\t\t\t\tif (type === 'x') {\n\t\t\t\t\tif (code.length !== 2) {\n\t\t\t\t\t\tthrow new Error(`Hexadecimal escape sequence in ${id} must be two characters`);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn String.fromCharCode(parseInt(code, 16));\n\t\t\t\t} else {\n\t\t\t\t\tif (code.length < 4 || code.length > 6) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Unicode escape sequence in ${id} must be between four and six characters`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn String.fromCodePoint(parseInt(code, 16));\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (/\\]\\[/.test(unescaped)) {\n\t\t\t\tthrow new Error(`Invalid route ${id} — parameters must be separated`);\n\t\t\t}\n","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/core/sync/create_manifest_data/index.js#L133-L169","documentation":"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.","triggerScenarios":"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.","commonSituations":"Confusing the `[x+..]` byte escape with the `[u+....]` Unicode escape that allows 4-6 digits; hand-writing escapes from memory.","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"],"exampleFix":"// before\n// src/routes/[x+abcd]/+page.svelte\n\n// after\n// src/routes/[u+0041]/+page.svelte   // or [x+41] for a single byte","handlingStrategy":"validation","validationCode":"function isValidHexEscape(name) {\n  const m = name.match(/^\\[x\\+([0-9a-f]+)\\]$/);\n  return !!m && m[1].length === 2;\n}\n// isValidHexEscape('[x+41]') -> true; isValidHexEscape('[x+abcd]') -> false","typeGuard":null,"tryCatchPattern":"try {\n  await build();\n} catch (e) {\n  if (String(e.message).includes('must be two characters')) {\n    console.error('[x+..] needs exactly 2 hex digits, or use [u+....] for codepoints');\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["routing","routes","unicode","validation"],"backgroundTag":"invalid-route-escape-sequence","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}