denoland/deno · error · TypeError
${prefix}: ${key} is invalid; ${e.message}
Error message
${prefix}: ${key} is invalid; ${e.message} What it means
Thrown by the URLPattern constructor (prefix: Failed to construct 'URLPattern') when one of the eight parsed components — protocol, username, password, hostname, port, pathname, search, hash — contains a pattern fragment that cannot be compiled into a RegExp with the 'u' (or 'ui' with ignoreCase) flag (ext/web/01_urlpattern.js:266). The native parser (op_urlpattern_parse) accepted the pattern text, but per the URLPattern spec every component is compiled into a regex for matching, and the underlying SyntaxError is rethrown as a TypeError that names the offending component key. The trailing e.message is the raw V8 regexp error, which pinpoints the broken group.
Source
Thrown at ext/web/01_urlpattern.js:268
const flags = options.ignoreCase ? "ui" : "u";
const components = [
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
];
for (let i = 0; i < 8; ++i) {
const key = COMPONENTS_KEYS[i];
const c = parsed[key];
try {
c.regexp = new SafeRegExp(c.regexpString, flags);
} catch (e) {
throw new TypeError(`${prefix}: ${key} is invalid; ${e.message}`);
}
components[i] = c;
}
this[_components] = components;
}
get protocol() {
webidl.assertBranded(this, URLPatternPrototype);
return this[_components][0].patternString;
}
get username() {
webidl.assertBranded(this, URLPatternPrototype);
return this[_components][1].patternString;
}
get password() {
webidl.assertBranded(this, URLPatternPrototype);View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Fix the RegExp syntax in the component named in the message (e.g. 'pathname is invalid'): balance group parens in :name(...) patterns and correct or complete any unicode/character-class escape.
- Reproduce the underlying error by compiling the group body alone: new RegExp(groupBody, 'u') — the SyntaxError message is the same one Deno reports.
- Wrap literal text that contains regex metacharacters like (, ), +, *, ?, [ in URLPattern's {...} literal-segment notation instead of escaping it.
- If patterns come from user config, validate each custom group with new RegExp(re, 'u') before constructing the URLPattern and reject bad input with a clear message.
Example fix
// before
const p = new URLPattern({ pathname: '/items/:id([0-9]+' });
// TypeError: Failed to construct 'URLPattern': pathname is invalid; Invalid regular expression: /([0-9+/: Unterminated group
// after
const p = new URLPattern({ pathname: '/items/:id([0-9]+)' }); Defensive patterns
Strategy: validation
Validate before calling
const groupOk = (re) => {
try { new RegExp(re, 'u'); return true; } catch { return false; }
};
if (!groupOk(cfg.idGroup)) throw new Error(`invalid route group: ${cfg.idGroup}`);
const p = new URLPattern({ pathname: `/items/:id(${cfg.idGroup})` }); Type guard
const isValidPatternGroup = (re) => {
try { new RegExp(re, 'u'); return true; } catch { return false; }
}; Try / catch
try {
pattern = new URLPattern(input);
} catch (e) {
if (e instanceof TypeError && e.message.includes("is invalid;")) {
return respondBadPattern(e.message);
}
throw e;
} Prevention
- Compile custom group bodies with new RegExp(re, 'u') before embedding them
- Use {...} literal segments for text containing regex metacharacters
- Centralize URLPattern construction in one helper that validates groups
When it happens
Trigger: new URLPattern({ pathname: '/users/:id([0-9+' }) (unbalanced group), new URLPattern('https://example.com/:year(\p{Year') (truncated unicode escape rejected under the 'u' flag), or { hostname: '[[:alpha' } — any component whose group text fails new SafeRegExp(text, 'u'|'ui') at ext/web/01_urlpattern.js:266.
Common situations: Porting Express/path-to-regexp route syntax into URLPattern; route tables assembled dynamically from config where group regex fragments are concatenated and a paren or bracket goes unbalanced; regex metacharacters in literal path segments left unquoted; template strings truncating unicode property escapes.
Related errors
- Can't convert url ("{}") to filename.
- Can't convert url ("{}") to filename.
- Bench attempted to exit with exit code: ${exitCode}
- ${prefix}Linter plugin name must be a string
- Request url protocol must be 'http:' or 'https:': received '
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/f2ce621fb4d9a75b.
Report an issue: GitHub.