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

  1. 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.
  2. Reproduce the underlying error by compiling the group body alone: new RegExp(groupBody, 'u') — the SyntaxError message is the same one Deno reports.
  3. Wrap literal text that contains regex metacharacters like (, ), +, *, ?, [ in URLPattern's {...} literal-segment notation instead of escaping it.
  4. 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

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


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/f2ce621fb4d9a75b. Report an issue: GitHub.