{"record":{"id":"19185393857bceac","repo":"apple/pkl","slug":"invalidglobinvalidescapecharacter","errorCode":"invalidGlobInvalidEscapeCharacter","errorMessage":"invalidGlobInvalidEscapeCharacter","messagePattern":"invalidGlobInvalidEscapeCharacter","errorType":"error_code","errorClass":"InvalidGlobPatternException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/GlobResolver.java","lineNumber":189,"sourceCode":"          } else {\n            sb.append('}');\n          }\n        }\n        case ',' -> {\n          if (inGroup) {\n            sb.append(\")|(?:\");\n          } else {\n            sb.append(',');\n          }\n        }\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 == '*') {","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/GlobResolver.java#L171-L207","documentation":"Pkl's GlobResolver translates glob patterns into Java regexes, and a backslash in a glob is an escape character that must be followed by one of ? * [ { or another backslash. If the character after the escape is anything else (e.g. \\d or \\s, which are regex escapes but not glob escapes), the pattern is rejected as invalid because it would silently change meaning. The error includes the offending character as a message parameter.","triggerScenarios":"Passing a glob pattern (e.g. to `glob(...)` imports or a glob-based resource/project resolution API such as GlobResolver.toRegexPattern/toRegexString) that contains a backslash not followed by ?, *, [, {, or \\\\ — most commonly regex-style escapes like \\d, \\w, \\., or a trailing backslash would instead raise invalidGlobInvalidTerminatingCharacter.","commonSituations":"Developers copying a regex into a glob field (\\d+ instead of [0-9]+), escaping spaces or dots out of habit, or shell-escaping a path that then carries stray backslashes into the pattern.","solutions":["Remove the backslash or replace the regex-style escape with glob syntax (e.g. \\d -> [0-9], \\. -> .)","If a literal character is meant, verify it does not need escaping in glob (only ? * [ ] { } \\ are special)","Double every backslash if the pattern passes through a layer that itself processes escapes (shell, properties file, JSON)"],"exampleFix":"// before\nglob(\"logs/\\d+/*.pkl\")\n// after\nglob(\"logs/[0-9]+/*.pkl\")","handlingStrategy":"validation","validationCode":"function isValidGlobEscape(pattern) {\n  return !/\\\\(?[^?*[\\\\{]|$)/.test(pattern); // false if a backslash precedes an unsupported char\n}","typeGuard":"function hasValidEscapes(p) {\n  for (let i = 0; i < p.length; i++) {\n    if (p[i] === '\\\\') {\n      const n = p[i+1];\n      if (n !== '?' && n !== '*' && n !== '[' && n !== '{' && n !== '\\\\') return false;\n      i++;\n    }\n  }\n  return true;\n}","tryCatchPattern":"try {\n  var regex = GlobResolver.toRegexPattern(glob);\n} catch (InvalidGlobPatternException e) {\n  // handle invalid glob: report message, fall back to literal path\n}","preventionTips":["Use character classes [0-9] instead of regex escapes like \\d in globs","Only escape glob metacharacters: ? * [ ] { } \\","Test glob patterns through toRegexPattern before shipping configs"],"tags":["glob","pattern","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-14T11:17:12.474Z"}