{"record":{"id":"cfa3fc85073f59cb","repo":"stanfordnlp/CoreNLP","slug":"invalid-match-group-for-entry-entry","errorCode":null,"errorMessage":"Invalid match group for entry ${entry}","messagePattern":"Invalid match group for entry (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/pipeline/TokensRegexNERAnnotator.java","lineNumber":391,"sourceCode":"      if (entry.tokensRegex != null) {\n        // TODO: posTagPatterns...\n        pattern = TokenSequencePattern.compile(env, entry.tokensRegex);\n      } else {\n        List<SequencePattern.PatternExpr> nodePatterns = new ArrayList<>(entry.regex.length);\n        for (String p:entry.regex) {\n          CoreMapNodePattern c = CoreMapNodePattern.valueOf(p, patternFlags);\n          if (posTagPattern != null) {\n            c.add(CoreAnnotations.PartOfSpeechAnnotation.class, posTagPattern);\n          }\n          nodePatterns.add(new SequencePattern.NodePatternExpr(c));\n        }\n        if (nodePatterns.size() == 1) {\n          nodePatterns = Collections.singletonList(nodePatterns.get(0));\n        }\n        pattern = TokenSequencePattern.compile(new SequencePattern.SequencePatternExpr(nodePatterns));\n      }\n      if (entry.annotateGroup < 0 || entry.annotateGroup > pattern.getTotalGroups()) {\n        throw new RuntimeException(\"Invalid match group for entry \" + entry);\n      }\n      pattern.setPriority(entry.priority);\n      pattern.setWeight(entry.weight);\n      patterns.add(pattern);\n      patternToEntry.put(pattern, entry);\n    }\n    return TokenSequencePattern.getMultiPatternMatcher(patterns);\n  }\n\n  private void annotateMatched(List<CoreLabel> tokens) {\n    List<SequenceMatchResult<CoreMap>> matched = multiPatternMatcher.findNonOverlapping(tokens);\n    for (SequenceMatchResult<CoreMap> m:matched) {\n      Entry entry = patternToEntry.get(m.pattern());\n\n      // Check if we will overwrite the existing annotation with this annotation\n      int g = entry.annotateGroup;\n      int start = m.start(g);\n      int end = m.end(g);","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/pipeline/TokensRegexNERAnnotator.java#L373-L409","documentation":"During createPatternMatcher, each mapping entry's declared 'group' column is validated against the compiled TokenSequencePattern's total group count; if annotateGroup < 0 or exceeds pattern.getTotalGroups(), a RuntimeException naming the entry is thrown. It means the mapping file asks to annotate a capture group the pattern never defines.","triggerScenarios":"A mapping file row has a 'group' value of e.g. 2 while its pattern contains only one parenthesized group; or a negative group value is written in the group column.","commonSituations":"Copying a pattern from another entry and forgetting to update the group column; editing a pattern to remove a capture group while leaving group=2; hand-written regexes in TokensRegex mapping files where counting groups off by one.","solutions":["Reduce the 'group' column value on the offending entry to a group that exists in the pattern (0 or 1 for single-group patterns).","Add a capture group to the pattern so the requested group index exists.","Remove the 'group' column from the row to fall back to the default group 0.","Re-run and read the entry name in the message to locate the exact mapping-file line."],"exampleFix":"// mapping file before (pattern has no group 2)\n[ { word:/CEO/ } ]\tgroup=2\n// after\n[ { word:/CEO/ } ]\tgroup=0","handlingStrategy":"validation","validationCode":"// Before loading: verify each group value fits its pattern's group count\nint groups = countCaptureGroups(patternText); // e.g. count unescaped '(' opening groups\nif (groupValue < 0 || groupValue > groups) throw new IllegalArgumentException(\"group \" + groupValue + \" invalid for pattern: \" + patternText);","typeGuard":null,"tryCatchPattern":"try { annotator = new TokensRegexNERAnnotator(name, props); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Invalid match group\")) { fixMappingFile(e.getMessage()); } else throw e; }","preventionTips":["Count capture groups in each pattern before assigning its group column","Omit the group column when you only need the full match (default 0)","Keep a small unit test that constructs the annotator against the shipped mapping file in CI"],"tags":["nlp","regex","mapping-file","config-error"],"backgroundTag":"value-out-of-range","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}