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

  1. Add the missing attribute (key='value') to the filter/token element in the rule XML so it matches the key passed to getRequired
  2. Check exact spelling and case of the key in both the XML file and the getRequired call; align them
  3. Temporarily log the full args map inside the filter to see which keys actually arrive and fix the mismatch
  4. 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

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


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/9ca1d22f5b81ff30. Report an issue: GitHub.