microsoft/playwright · error · Error
Invalid glob pattern ${JSON.stringify(glob)}: nested '{' is
Error message
Invalid glob pattern ${JSON.stringify(glob)}: nested '{' is not supported What it means
Thrown by globToRegexPattern when a `{` is encountered while already inside a brace group (inGroup is true). The glob-to-regex converter supports single-level alternation `{a,b}` but does not support nesting, so a second `{` before the group closes is rejected.
Source
Thrown at packages/isomorphic/urlMatch.ts:68
if (charAfter === '/') {
if (charBefore === '/')
tokens.push('((.+/)|)');
else
tokens.push('(.*/)');
++i;
} else {
tokens.push('(.*)');
}
} else {
tokens.push('([^/]*)');
}
continue;
}
switch (c) {
case '{':
if (inGroup)
throw new Error(`Invalid glob pattern ${JSON.stringify(glob)}: nested '{' is not supported`);
inGroup = true;
tokens.push('(');
break;
case '}':
if (!inGroup)
throw new Error(`Invalid glob pattern ${JSON.stringify(glob)}: unmatched '}'`);
inGroup = false;
tokens.push(')');
break;
case ',':
if (inGroup) {
tokens.push('|');
break;
}
tokens.push('\\' + c);
break;
default:
tokens.push(escapedChars.has(c) ? '\\' + c : c);View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Flatten the alternation into a single level: `{a,b,c}` instead of `{a,{b,c}}`.
- Split into multiple route handlers if true nesting semantics are required.
- Switch to a RegExp match for complex alternation logic.
Example fix
// before
page.route('**/{api,{v1,v2}}/*', handler); // nested brace
// after
page.route('**/{api,v1,v2}/*', handler); Defensive patterns
Strategy: validation
Validate before calling
function assertNoNestedBraces(glob: string) {
let depth = 0;
for (const c of glob) {
if (c === '{') depth++;
if (c === '}') depth--;
if (depth > 1) throw new Error(`Glob has nested braces: ${glob}`);
if (depth < 0) throw new Error(`Glob has unmatched }: ${glob}`);
}
if (depth !== 0) throw new Error(`Glob has unmatched {: ${glob}`);
} Type guard
function isFlatGlob(glob: string): boolean {
let depth = 0;
for (const c of glob) {
if (c === '{') depth++;
else if (c === '}') depth--;
if (depth > 1) return false;
}
return depth === 0;
} Try / catch
try {
page.route(glob, handler);
} catch (e) {
if (/nested '\{' is not supported/.test(e.message)) {
glob = flattenAlternation(glob); // user-supplied flattener
page.route(glob, handler);
} else throw e;
} Prevention
- Keep glob alternation to a single level.
- Use RegExp for nested OR logic.
- Add a unit test for any glob builder that interpolates lists.
When it happens
Trigger: Passing a glob with nested alternation to urlMatches/route, e.g. `'{a,{b,c}}'`, `page.route('**/{foo,{bar,baz}}', ...)`, or `page.goto` baseURL glob with `{...{...}...}`. Triggered in the `case '{'` branch when inGroup is already true.
Common situations: Copying a shell/extglob pattern into a Playwright URL glob; attempting nested OR groups; building globs from templated fragments that double up braces.
Related errors
- Invalid glob pattern ${JSON.stringify(glob)}: unmatched '}'
- Invalid glob pattern ${JSON.stringify(glob)}: unmatched '{'
- Error while parsing selector `${selector}` - selector cannot
- url parameter should be string, RegExp, URLPattern or functi
- Unsupported token "${unsupportedToken.toSource()}" while par
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/51c962e2fe7eb88d.
Report an issue: GitHub.