{"record":{"id":"49466e9caa168e36","repo":"apple/pkl","slug":"invalidglobmissingcharacterclassterminator","errorCode":"invalidGlobMissingCharacterClassTerminator","errorMessage":"invalidGlobMissingCharacterClassTerminator","messagePattern":"invalidGlobMissingCharacterClassTerminator","errorType":"error_code","errorClass":"InvalidGlobPatternException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/GlobResolver.java","lineNumber":110,"sourceCode":"    var i = idx;\n    switch (getNextChar(globPattern, i)) {\n      case '^' -> {\n        // verbatim; escape\n        sb.append(\"\\\\^\");\n        i++;\n      }\n      case '!' -> {\n        // negation\n        sb.append(\"^\");\n        i++;\n      }\n      case ']' -> {\n        // the first `]` in a character class is verbatim and not treated as a closing delimiter.\n        sb.append(']');\n        i++;\n      }\n      case NULL ->\n          throw new InvalidGlobPatternException(\n              ErrorMessages.create(\"invalidGlobMissingCharacterClassTerminator\"));\n    }\n    i++;\n    var current = globPattern.charAt(i);\n    while (current != ']') {\n      if (current == '[') {\n        var next = getNextChar(globPattern, i);\n        if (next == ':' || next == '=' || next == '.') {\n          throw new InvalidGlobPatternException(\n              ErrorMessages.create(\"invalidGlobUnsupportedFeature\"));\n        }\n      }\n      if (current == '/') {\n        throw new InvalidGlobPatternException(\n            ErrorMessages.create(\"invalidGlobInvalidCharacterInCharacterClass\", current));\n      } else if (current == '\\\\') {\n        sb.append(\"\\\\\\\\\");\n      } else {","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/GlobResolver.java#L92-L128","documentation":"When converting a glob pattern to a regex, a character class `[...]` must be terminated by `]`. consumeCharacterClass throws InvalidGlobPatternException with this code if the input ends (NULL sentinel) before the class is closed.","triggerScenarios":"Passing a glob pattern with an unterminated character class to GlobResolver.toRegexString/toRegexPattern, e.g. `src/[abc` with no closing `]`.","commonSituations":"Typos in glob patterns in project config (exclude/include lists); patterns built by string concatenation where the closing bracket was dropped; user-supplied ignore patterns.","solutions":["Add the missing closing `]` to the character class in the glob pattern.","Validate the glob pattern syntax before passing it to the resolver.","Escape a literal `[` if a character class was not intended."],"exampleFix":"// before\nglob = \"src/[abc\"\n// after\nglob = \"src/[abc]\"","handlingStrategy":"validation","validationCode":"boolean hasBalancedBrackets(String glob) {\n  int open = 0;\n  for (char c : glob.toCharArray()) { if (c == '[') open++; if (c == ']' && open > 0) open--; }\n  return open == 0;\n}\n","typeGuard":null,"tryCatchPattern":"try { pattern = GlobResolver.toRegexPattern(glob); } catch (InvalidGlobPatternException e) { throw new IllegalArgumentException(\"Bad glob: \" + glob, e); }\n","preventionTips":["Validate globs at config-load time.","Escape literal `[` as `\\\\[` when a class is not intended.","Lint patterns in CI."],"tags":["pkl","glob","pattern","validation"],"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-14T16:17:12.679Z"}