languagetool-org/languagetool · error · IllegalArgumentException
AdvancedSynthesizerFilter: Index out of bounds in ${match.ge
Error message
AdvancedSynthesizerFilter: Index out of bounds in ${match.getRule().getFullId()}, value: ${postagFromStr} What it means
AbstractAdvancedSynthesizerFilter.acceptRuleMatch() parses the rule's 'postagFrom' argument (absolute int or 'marker+N' offset) and validates it indexes into the matched pattern tokens (1..patternTokens.length). A value outside that range means the synthesizer rule misconfiguration references a token that doesn't exist in the match, so it throws.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/AbstractAdvancedSynthesizerFilter.java:74
String lemmaSelect = getRequired("lemmaSelect", arguments);
String postagFromStr = getRequired("postagFrom", arguments);
String lemmaFromStr = getRequired("lemmaFrom", arguments);
String newLemma = getOptional("newLemma", arguments, "");
int postagFrom = 0;
if (postagFromStr.startsWith("marker")) {
while (postagFrom < patternTokens.length && patternTokens[postagFrom].getStartPos() < match.getFromPos()) {
postagFrom++;
}
postagFrom++;
if (postagFromStr.length()>6) {
postagFrom += Integer.parseInt(postagFromStr.replace("marker", ""));
}
} else {
postagFrom = Integer.parseInt(postagFromStr);
}
if (postagFrom < 1 || postagFrom > patternTokens.length) {
throw new IllegalArgumentException("AdvancedSynthesizerFilter: Index out of bounds in "
+ match.getRule().getFullId() + ", value: " + postagFromStr);
}
int lemmaFrom = 0;
if (lemmaFromStr.startsWith("marker")) {
while (lemmaFrom < patternTokens.length && patternTokens[lemmaFrom].getStartPos() < match.getFromPos()) {
lemmaFrom++;
}
lemmaFrom++;
if (lemmaFromStr.length()>6) {
lemmaFrom += Integer.parseInt(lemmaFromStr.replace("marker", ""));
}
} else {
lemmaFrom = Integer.parseInt(lemmaFromStr);
}
if (lemmaFrom < 1 || lemmaFrom > patternTokens.length) {
throw new IllegalArgumentException("AdvancedSynthesizerFilter: Index out of bounds in "
+ match.getRule().getFullId() + ", value: " + lemmaFromStr);
}View on GitHub (pinned to 2e990059ce)
Solutions
- Fix postag_from in the rule XML so it points to an existing token (1-based) within the matched pattern.
- Recount the rule pattern tokens after edits and update all *_from/*_to references.
- Check 'marker' arithmetic: the resolved marker+N must stay within patternTokens.length.
- Test the rule with LanguageTool's rule validation (e.g. via the rule editor or validateRuls tests) before deploying.
Example fix
// before (pattern has 2 tokens) <filter class="...AdvancedSynthesizerFilter" args="postag_from:5 lemma_from:1"/> // after <filter class="...AdvancedSynthesizerFilter" args="postag_from:1 lemma_from:1"/>
Defensive patterns
Strategy: validation
Validate before calling
// at rule-authoring time
int postagFrom = Integer.parseInt(args.get("postag_from").replace("marker", ""));
if (postagFrom < 1 || postagFrom > patternTokens.length)
throw new RuleFormatException("postag_from out of range"); Prevention
- Recheck filter arg indices whenever a rule pattern changes
- Remember indices are 1-based
- Keep marker arithmetic within the token count
- Run rule test sentences in CI
When it happens
Trigger: A rule using an AdvancedSynthesizerFilter supplies postagFrom (e.g. postag_from="5" or postag_from="marker:2" resolved value) that is <1 or greater than the number of tokens actually matched by the rule pattern.
Common situations: Editing a rule pattern to fewer tokens without updating postag_from; off-by-one confusion (positions are 1-based); using marker arithmetic that overshoots the token count.
Related errors
- AdvancedSynthesizerFilter: Index out of bounds in ${match.ge
- AdvancedSynthesizerFilter: undefined POS tag for rule ${matc
- Cannot synthesize <token><exception>
- Only 3grams and 4grams are supported
- Set only 'weekDay' and 'date' for " + YMDDateCheckFilter.cla
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/b5c6273da0689aba.
Report an issue: GitHub.