{"record":{"id":"bf71cdb7abd970b6","repo":"denoland/deno","slug":"pattern-cannot-start-with-at","errorCode":null,"errorMessage":"Pattern cannot start with \"?\" at {}.","messagePattern":"Pattern cannot start with \"\\?\" at (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/lsp/path_to_regex.rs","lineNumber":140,"sourceCode":"          }\n        }\n        if name.is_empty() {\n          return Err(anyhow!(\"Missing parameter name at {}\", index));\n        }\n        let name_len = name.len();\n        tokens.push(LexToken {\n          token_type: TokenType::Name,\n          index,\n          value: name,\n        });\n        index += 1 + name_len;\n      }\n      Some('(') => {\n        let mut count = 1;\n        let mut pattern = String::new();\n\n        if chars.peek() == Some(&'?') {\n          return Err(anyhow!(\n            \"Pattern cannot start with \\\"?\\\" at {}.\",\n            index + 1\n          ));\n        }\n\n        loop {\n          let next_char = chars.peek();\n          if next_char.is_none() {\n            break;\n          }\n          if next_char == Some(&'\\\\') {\n            pattern.push(chars.next().unwrap());\n            pattern.push(\n              chars\n                .next()\n                .ok_or_else(|| anyhow!(\"Unexpected termination of string.\"))?,\n            );\n            continue;","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/cli/lsp/path_to_regex.rs#L122-L158","documentation":"cli/lsp/path_to_regex.rs:140 lexes the parenthesized regex part of a placeholder. If the first character inside '(' is '?', it errors with \"Pattern cannot start with \\\"?\\\"\" — a leading '?' would make the whole custom pattern optional, which the token model forbids (optionality belongs on the placeholder, via '{name?}', not the regex).","triggerScenarios":"A schema placeholder whose inline pattern begins with '?', e.g. \"/x/:pkg(?i)\" or \"/x/:pkg(?[a-z]+)\"; attempts to inline regex flags like (?i) directly after the colon-name.","commonSituations":"Registry authors pasting PCRE with flags into the pattern slot; trying to express optional matching via '?' at pattern start instead of the placeholder's optional marker.","solutions":["Remove the leading '?': \"/x/:pkg([a-z]+)\"","Wrap flag-style constructs in a non-capturing group: \"/x/:pkg((?i)[a-z]+)\" — the outer group now starts with '(' so it passes","For optional segments use the placeholder syntax \"/x/{name?}\" instead of a '?' in the pattern"],"exampleFix":"// before\n{ \"schema\": \"/x/:pkg(?i)\" }\n\n// after\n{ \"schema\": \"/x/:pkg((?i)[a-z]+)\" }","handlingStrategy":"validation","validationCode":"const m = schema.match(/\\((\\?)/); // '(' immediately followed by '?'\nif (m) throw new Error(`pattern starts with '?' near index ${m.index}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wrap flag constructs in an outer group: ((?i)...)","Express optional placeholders via {name?}, never a leading '?' in the pattern"],"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"}