{"record":{"id":"401974959596fb32","repo":"denoland/deno","slug":"capturing-groups-are-not-allowed-at","errorCode":null,"errorMessage":"Capturing groups are not allowed at {}.","messagePattern":"Capturing groups are not allowed at (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/lsp/path_to_regex.rs","lineNumber":170,"sourceCode":"            pattern.push(chars.next().unwrap());\n            pattern.push(\n              chars\n                .next()\n                .ok_or_else(|| anyhow!(\"Unexpected termination of string.\"))?,\n            );\n            continue;\n          }\n          if next_char == Some(&')') {\n            count -= 1;\n            if count == 0 {\n              chars.next();\n              break;\n            }\n          } else if next_char == Some(&'(') {\n            count += 1;\n            pattern.push(chars.next().unwrap());\n            if chars.peek() != Some(&'?') {\n              return Err(anyhow!(\n                \"Capturing groups are not allowed at {}.\",\n                index + pattern.len()\n              ));\n            }\n            continue;\n          }\n\n          pattern.push(chars.next().unwrap());\n        }\n\n        if count > 0 {\n          return Err(anyhow!(\"Unbalanced pattern at {}.\", index));\n        }\n        if pattern.is_empty() {\n          return Err(anyhow!(\"Missing pattern at {}.\", index));\n        }\n        let pattern_len = pattern.len();\n        tokens.push(LexToken {","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/cli/lsp/path_to_regex.rs#L152-L188","documentation":"cli/lsp/path_to_regex.rs:170: inside a placeholder's custom pattern, an inner '(' bumps the group counter; if the character after it is not '?', the group is a capturing group, which path-to-regexp forbids because the token model already captures each placeholder itself. The error reports the offset (index + pattern length) of the offending '('.","triggerScenarios":"A schema pattern with a capture group: \"/x/:pkg((\\\\d+))\" or \"/x/:file((foo|bar))\"; alternations written without '?:'.","commonSituations":"Registry authors pasting ordinary regex (which uses capturing groups freely) into the pattern slot; refactoring from string-to-regex code that relied on capture indices.","solutions":["Convert inner groups to non-capturing: \"/x/:pkg((?:\\\\d+))\", \"/x/:file((?:foo|bar))\"","Audit every '(' inside patterns and add '?:' unless it starts a group construct like (?= or (?! which already begin with '?'","Test the schema against path-to-regexp before publishing the registry config"],"exampleFix":"// before\n{ \"schema\": \"/x/:pkg((\\\\d+))\" }\n\n// after\n{ \"schema\": \"/x/:pkg((?:\\\\d+))\" }","handlingStrategy":"validation","validationCode":"function hasCapturingGroup(pattern: string): boolean {\n  let depth = 0;\n  for (let i = 0; i < pattern.length; i++) {\n    const c = pattern[i];\n    if (c === \"\\\\\") { i++; continue; }\n    if (c === \"(\" && pattern[i + 1] !== \"?\") return true;\n  }\n  return false;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Habit: every '(' you type in a schema pattern is followed by '?:'","Lint pasted regexes for raw capture groups before inlining them into schemas"],"tags":["lsp","registry","schema","regex"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}