languagetool-org/languagetool · error · RuntimeException
Got " + matcher.groupCount() + " groups for regex '" + patte
Error message
Got " + matcher.groupCount() + " groups for regex '" + pattern.pattern() + "', expected 2
What it means
Companion to error 54: when the filter arg two_groups_regexp is set, PartialPosTagFilter requires the regex to have exactly 2 capturing groups (second group appended to the partial token). This RuntimeException is thrown when groupCount() != 2 while two_groups_regexp is true.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/PartialPosTagFilter.java:84
String suffix = "";
if (args.containsKey("prefix")) {
prefix = args.get("prefix");
};
if (args.containsKey("suffix")) {
suffix = args.get("suffix");
};
String token = prefix + patternTokens[tokenPos - 1].getToken() + suffix;
Matcher matcher = pattern.matcher(token);
if ((matcher.groupCount() != 1) && !(two_groups_regexp)) {
throw new RuntimeException("Got " + matcher.groupCount() + " groups for regex '" + pattern.pattern() + "', expected 1");
}
if ((matcher.groupCount() != 2) && (two_groups_regexp)) {
throw new RuntimeException("Got " + matcher.groupCount() + " groups for regex '" + pattern.pattern() + "', expected 2");
}
if (matcher.matches()) {
String partialToken = matcher.group(1);
if (matcher.groupCount() == 2) {
partialToken += matcher.group(2);
}
List<AnalyzedTokenReadings> tags = tag(partialToken);
if (tags != null && partialTagHasRequiredTag(tags, requiredTagRegexp, negatePos)) {
return match;
}
return null;
}
return null;
}
private boolean partialTagHasRequiredTag(List<AnalyzedTokenReadings> tags, String requiredTagRegexp, boolean negatePos) {
// Without negate_pos=yes: return true if any postag matches the regexp.
// With negate_pos=yes: return true if there are postag and none them matches the regexp.View on GitHub (pinned to 2e990059ce)
Solutions
- Make the regex contain exactly two capturing groups, e.g. 'pre(.*)post(.*)'.
- If only one group is needed, remove the two_groups_regexp arg instead.
- Verify group count programmatically before deploying the rule.
Example fix
<!-- before --> <filter class="...PartialPosTagFilter" args="no:1 two_groups_regexp regexp:(.*)ing postag_regexp:VBZ"/> <!-- after --> <filter class="...PartialPosTagFilter" args="no:1 two_groups_regexp regexp:(.*)(ing) postag_regexp:VBZ"/>
Defensive patterns
Strategy: validation
Validate before calling
java.util.regex.Pattern p = java.util.regex.Pattern.compile(regexp);
if (twoGroups && p.matcher("").groupCount() != 2) {
throw new IllegalArgumentException("two_groups_regexp requires exactly 2 capturing groups");
} Try / catch
try {
return filter.acceptRuleMatch(match, args, pos, tokens, tokenPositions);
} catch (RuntimeException e) {
throw new RuleFormatException("Bad two_groups_regexp pattern: " + e.getMessage(), e);
} Prevention
- Only set two_groups_regexp when the regex really has 2 groups
- Count '(' occurrences (excluding escaped \( and (?:) before setting the flag
- Keep single-group and two-group rule variants in separate test files
When it happens
Trigger: Declaring two_groups_regexp in the filter args but supplying a regex with fewer or more than two capturing groups.
Common situations: Enabling two_groups_regexp for an infix/prefix match but leaving the regex from a single-group example; escaping mistakes that turn '(' groups into literals.
Related errors
- Got " + matcher.groupCount() + " groups for regex '" + patte
- suppressMisspelledMatch must be a valid regex
- suppressMisspelledSuggestions must be a valid regex
- Format error in file ${path}, line: ${line}
- No IssueType found for name '" + name + "'. Valid values: "
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/a41fe2435b46928c.
Report an issue: GitHub.