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

  1. Use exactly two hex digits for [x+..], e.g. `[x+41]`
  2. Switch to `[u+....]` (4-6 hex digits) if you meant a Unicode codepoint like `[u+1f600]`
  3. 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

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


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