{"record":{"id":"67d968bbef2e644d","repo":"languagetool-org/languagetool","slug":"unexpected-reference-to-capturing-group-in-rule-wi","errorCode":null,"errorMessage":"Unexpected reference to capturing group in rule with id %s.","messagePattern":"Unexpected reference to capturing group in rule with id (.+?)\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/RegexPatternRule.java","lineNumber":124,"sourceCode":"        String processedSuggestionsOutMsg = processMessage(patternMatcher, suggestionsOutMsg, backReferencesInSuggestionsOutMsg,\n                suggestionsInSuggestionsOutMsg, getSuggestionMatchesOutMsg());\n\n        boolean startsWithUpperCase = patternMatcher.start() == 0 && Character.isUpperCase(text.charAt(patternMatcher.start()));\n        RuleMatch ruleMatch = new RuleMatch(this, sentenceObj, markStart, markEnd, patternMatcher.start(), patternMatcher.end(),\n                processedMessage, shortMessage, startsWithUpperCase, false, processedSuggestionsOutMsg, true);\n        if (regexFilter != null) {\n          RegexRuleFilterEvaluator ruleFilterEvaluator = new RegexRuleFilterEvaluator(regexFilter);\n          RuleMatch filteredMatch = ruleFilterEvaluator.runFilter(getFilterArguments(), ruleMatch, sentenceObj, patternMatcher);\n          if (filteredMatch != null) {\n            matches.add(ruleMatch);\n          }\n        } else {\n          matches.add(ruleMatch);\n        }\n\n        startPos = patternMatcher.end();\n      } catch (IndexOutOfBoundsException e){\n        throw new RuntimeException(String.format(\"Unexpected reference to capturing group in rule with id %s.\", this.getFullId()), e);\n      } catch (Exception e) {\n        throw new RuntimeException(String.format(\"Unexpected exception when processing regexp in rule with id %s.\", this.getFullId()), e);\n      }\n    }\n    return matches.toArray(RuleMatch.EMPTY_ARRAY);\n  }\n\n  @NotNull\n  private List<Pair<Integer, Integer>> getClausePositionsInMessage(Pattern pattern, String message) {\n    Matcher matcher = pattern.matcher(message);\n    List<Pair<Integer, Integer>> clausePositionsInMessage = new ArrayList<>();\n    while (matcher.find()) {\n      clausePositionsInMessage.add(Pair.of(matcher.start(), matcher.end()));\n    }\n    return clausePositionsInMessage;\n  }\n\n  private String processMessage(Matcher matcher, String message, List<Pair<Integer, Integer>> backReferences,","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/RegexPatternRule.java#L106-L142","documentation":"Raised while a regex-based XML rule matches: the rule's message or suggestion text references a capturing group (a back-reference like \\1) that the rule's regular expression never captured. The faulty input is the rule's <message>/<suggestion> markup referencing a group number that does not exist in the pattern.","triggerScenarios":"Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/RegexPatternRule.java:124 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Add the missing capturing parentheses to the rule's regular expression so the referenced group exists","Correct the back-reference number in the message so it points to an existing group","Refer to the rule id quoted in the exception to locate and fix the offending grammar.xml entry"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}