{"record":{"id":"3526fc5096155dde","repo":"apple/pkl","slug":"invalidglobextglob","errorCode":"invalidGlobExtGlob","errorMessage":"invalidGlobExtGlob","messagePattern":"invalidGlobExtGlob","errorType":"error_code","errorClass":"InvalidGlobPatternException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/GlobResolver.java","lineNumber":199,"sourceCode":"        }\n        case '\\\\' -> {\n          var next = getNextChar(globPattern, i);\n          if (next == NULL) {\n            throw new InvalidGlobPatternException(\n                ErrorMessages.create(\"invalidGlobInvalidTerminatingCharacter\"));\n          }\n          if (next != '?' && next != '*' && next != '[' && next != '{' && next != '\\\\') {\n            throw new InvalidGlobPatternException(\n                ErrorMessages.create(\"invalidGlobInvalidEscapeCharacter\", next));\n          }\n          sb.append('\\\\').append(next);\n          i++;\n        }\n        case '[' -> i = consumeCharacterClass(globPattern, i, sb);\n        case '?' -> {\n          var next = getNextChar(globPattern, i);\n          if (next == '(') {\n            throw new InvalidGlobPatternException(ErrorMessages.create(\"invalidGlobExtGlob\"));\n          }\n          sb.append(\".\");\n        }\n        case '*' -> {\n          var next = getNextChar(globPattern, i);\n          if (next == '(') {\n            throw new InvalidGlobPatternException(ErrorMessages.create(\"invalidGlobExtGlob\"));\n          } else if (next == '*') {\n            // globstar, crosses directory boundaries\n            sb.append(\".*\");\n            i++;\n          } else {\n            // single wildcard matches everything up until the next directory character\n            sb.append(\"[^/]*\");\n          }\n        }\n        case '+', '@' -> {\n          var next = getNextChar(globPattern, i);","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/GlobResolver.java#L181-L217","documentation":"GlobResolver rejects extended-glob syntax: a `?` immediately followed by `(` would begin an extglob alternation like ?(a|b), which this glob implementation does not support. A plain `?` matches exactly one character, so `?(` is rejected rather than misinterpreted.","triggerScenarios":"Calling toRegexPattern/toRegexString (via glob import or resource glob resolution) with a pattern where `?` is directly followed by `(`, e.g. \"?(main|test).pkl\".","commonSituations":"Copying patterns from bash with extglob enabled (shopt -s extglob) or from tools like minimatch/jq that support extglob syntax into a Pkl glob.","solutions":["Rewrite the extglob alternation as a brace or character-class expansion, e.g. \"?(main|test).pkl\" -> \"{main,test}.pkl\"","Escape or restructure so `(` is not immediately after `?` — a literal `(` should appear as `(` alone (it is escaped by the translator) not right after a wildcard","Use separate globs for each alternative"],"exampleFix":"// before\nglob(\"?(a|b).pkl\")\n// after\nglob(\"{a,b}.pkl\")","handlingStrategy":"validation","validationCode":"/\\?\\(/.test(glob) // true means unsupported extglob ?( — rewrite before use","typeGuard":"const supportsPlainGlobOnly = (p) => !/\\?\\(/.test(p);","tryCatchPattern":"try {\n  var regex = GlobResolver.toRegexPattern(glob);\n} catch (InvalidGlobPatternException e) {\n  if (e.getMessage().contains(\"extglob\")) throw new IllegalArgumentException(\"extglob ?( syntax unsupported; use {a,b}\");\n  throw e;\n}","preventionTips":["Do not copy bash extglob patterns into Pkl globs","Prefer brace expansion {a,b} over extglob alternations","Document that only ? * ** [..] {..} \\ are supported"],"tags":["glob","extglob","pkl"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}