{"record":{"id":"9dc8955a943be494","repo":"languagetool-org/languagetool","slug":"wrong-position-in-whitespacecheckfilter-pos","errorCode":null,"errorMessage":"Wrong position in WhitespaceCheckFilter: \" + pos + \", must be 1 to \" + patternTokens.length","messagePattern":"Wrong position in WhitespaceCheckFilter: \" \\+ pos \\+ \", must be 1 to \" \\+ patternTokens\\.length","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/WhitespaceCheckFilter.java","lineNumber":35,"sourceCode":" * USA\n */\npackage org.languagetool.rules;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.languagetool.AnalyzedTokenReadings;\nimport org.languagetool.rules.patterns.RuleFilter;\n\npublic class WhitespaceCheckFilter extends RuleFilter  {\n\n  @Override\n  public RuleMatch acceptRuleMatch(RuleMatch match, Map<String, String> arguments, int patternTokenPos,\n                                   AnalyzedTokenReadings[] patternTokens, List<Integer> tokenPositions) {\n    String wsChar = getRequired(\"whitespaceChar\", arguments);\n    int pos = Integer.parseInt(getRequired(\"position\", arguments));\n    if (pos < 1 || pos > patternTokens.length) {\n      throw new IllegalArgumentException(\"Wrong position in WhitespaceCheckFilter: \" + pos + \", must be 1 to \" + patternTokens.length);\n    }\n    if (!patternTokens[pos - 1].getWhitespaceBefore().equals(wsChar)) {\n      return match;\n    } else {\n      return null;\n    }\n  }\n\n}\n","sourceCodeStart":17,"sourceCodeEnd":45,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/WhitespaceCheckFilter.java#L17-L45","documentation":"WhitespaceCheckFilter.acceptRuleMatch validates the 'position' argument of a whitespace-check XML rule. This IllegalArgumentException is thrown when the configured position is less than 1 or greater than the number of pattern tokens, since it indexes into patternTokens.","triggerScenarios":"A rule XML uses a whitespace_check filter with <position> set to 0, negative, or a value larger than the number of tokens matched by the rule's pattern.","commonSituations":"Authoring custom GrammarXML rules with an off-by-one position (positions are 1-based); a rule pattern was shortened without updating the filter's position attribute.","solutions":["Set 'position' in the rule XML to a value between 1 and the number of pattern tokens.","Remember positions are 1-based, so the first token is position 1.","If the pattern changed, recount tokens (including skipped/inflected placeholders) and update the position."],"exampleFix":"// before (rule XML)\n<filter class=\"...WhitespaceCheckFilter\" position=\"0\"/>\n// after (rule XML)\n<filter class=\"...WhitespaceCheckFilter\" position=\"1\"/>","handlingStrategy":"validation","validationCode":"// validate the rule before running LT\nint pos = Integer.parseInt(attrs.get(\"position\"));\nif (pos < 1 || pos > patternTokenCount)\n    throw new IllegalArgumentException(\"position must be 1..\" + patternTokenCount);","typeGuard":null,"tryCatchPattern":"try { rule.match(...); } catch (IllegalArgumentException e) { log.error(\"Bad whitespace_check rule config: \" + e.getMessage()); }","preventionTips":["Remember positions are 1-based in LT rule XML","Recount pattern tokens after any pattern edit","Add unit tests that execute every custom rule against sample text"],"tags":["java","rule-xml","argument-validation","languagetool"],"backgroundTag":"value-out-of-range","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}