languagetool-org/languagetool · error · IllegalArgumentException
Missing key '${key}'
Error message
Missing key '${key}' What it means
RuleFilter.getRequired() is a helper for custom RuleFilter implementations in LanguageTool. It looks up a key in the filter's argument map (the key='value' attributes of the <filter> element / token properties in the rule XML). When the map has no entry for the requested key it throws IllegalArgumentException, because the filter cannot do its job without that value.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/RuleFilter.java:70
@Nullable
public abstract RuleMatch acceptRuleMatch(RuleMatch match, Map<String, String> arguments, int patternTokenPos, AnalyzedTokenReadings[] patternTokens, List<Integer> tokenPositions) throws IOException;
/** @since 3.2 */
public boolean matches(Map<String, String> arguments, AnalyzedTokenReadings[] patternTokens, int firstMatchToken, List<Integer> tokenPositions) throws IOException {
RuleMatch fakeMatch = new RuleMatch(new FakeRule(), null, 0, 1, "(internal rule)");
return acceptRuleMatch(fakeMatch, arguments, firstMatchToken, patternTokens, tokenPositions) != null;
}
private static class FakeRule extends Rule {
@Override public String getId() { return "FAKE-RULE-FOR-FILTER"; }
@Override public String getDescription() { return "<none>"; }
@Override public RuleMatch[] match(AnalyzedSentence sentence) throws IOException { return RuleMatch.EMPTY_ARRAY; }
}
protected String getRequired(String key, Map<String, String> map) {
String result = map.get(key);
if (result == null) {
throw new IllegalArgumentException("Missing key '" + key + "'");
}
return result;
}
protected String getOptional(String key, Map<String, String> map) {
return map.get(key);
}
protected String getOptional(String key, Map<String, String> map, String defaultValue) {
String value = map.get(key);
if (value == null) {
return defaultValue;
}
return value;
}
protected int getPosition(String fromStr, AnalyzedTokenReadings[] patternTokens, RuleMatch match) {
int i;View on GitHub (pinned to 2e990059ce)
Solutions
- Add the missing attribute (key='value') to the filter/token element in the rule XML so it matches the key passed to getRequired
- Check exact spelling and case of the key in both the XML file and the getRequired call; align them
- Temporarily log the full args map inside the filter to see which keys actually arrive and fix the mismatch
- If the key is genuinely optional, switch the call to getOptional(key, map) and handle null
Example fix
// before (XML) <token regexp="yes">...</token> // after (XML) <token regexp="yes" postag_regexp="yes" postag="NN.*"/>
Defensive patterns
Strategy: validation
Validate before calling
Set<String> required = Set.of("postag", "position");
Set<String> provided = args.keySet();
java.util.List<String> missing = new java.util.ArrayList<>(required);
missing.removeAll(provided);
if (!missing.isEmpty()) throw new IllegalArgumentException("Filter args missing keys: " + missing); Type guard
if (args != null && args.containsKey(key)) { /* safe to getRequired */ } Try / catch
try {
String value = getRequired(key, args);
} catch (IllegalArgumentException e) {
throw new RuleFilterInitializationException("Rule " + ruleId + " misconfigured: " + e.getMessage(), e);
} Prevention
- Keep key names in the rule XML and getRequired calls in a shared constant list
- Test each rule XML that uses a filter in a unit test so a missing attribute fails at build time
- Log the full args map when debugging filter issues
- Use getOptional only for keys that are genuinely optional
When it happens
Trigger: A RuleFilter subclass calls getRequired("someKey", args) but the rule XML that references the filter does not define the matching attribute, or the attribute name in XML and the key string in Java differ in case or spelling.
Common situations: Renaming an XML attribute in a grammar/rule file without updating the filter class (or vice versa); copying a filter element from another rule and forgetting to add a required attribute; typos like 'postag' vs 'posTag' in the map key.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- suppressMisspelledMatch must be a valid regex
- suppressMisspelledSuggestions must be a valid regex
- RuleFilter: Index out of bounds in ${match.getRule().getFull
- AbstractAdvancedSynthesizerFilter only works with pattern ru
- Format error in file ${path}, line: ${line}
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/9ca1d22f5b81ff30.
Report an issue: GitHub.