languagetool-org/languagetool · error · RuntimeException

Could not find rule '${ruleId}' for language ${language} in

Error message

Could not find rule '${ruleId}' for language ${language} in files: ${filenames}

What it means

PatternRuleXmlCreator.toXML() throws this RuntimeException when it searched all known rule XML files for the language but found no rulegroup matching the given rule id. It is a lookup failure: the id does not exist (or is misspelled) in any of the listed files. The message includes the exact filenames searched.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleXmlCreator.java:79

          NodeList ruleGroupNodes = (NodeList) xpath.evaluate("/rules/category/rulegroup[@id='" + ruleId.getId() + "']/rule", doc, XPathConstants.NODESET);
          if (ruleGroupNodes != null) {
            for (int i = 0; i < ruleGroupNodes.getLength(); i++) {
              if (Integer.toString(i+1).equals(ruleId.getSubId())) {
                return nodeToString(ruleGroupNodes.item(i));
              }
            }
          }
        } else {
          Node ruleGroupNode = (Node) xpath.evaluate("/rules/category/rulegroup[@id='" + ruleId.getId() + "']", doc, XPathConstants.NODE);
          if (ruleGroupNode != null) {
            return nodeToString(ruleGroupNode);
          }
        }
      } catch (Exception e) {
        throw new RuntimeException("Could not turn rule '" + ruleId + "' for language " + language + " into a string", e);
      }
    }
    throw new RuntimeException("Could not find rule '" + ruleId + "' for language " + language + " in files: " + filenames);
  }

  private Document getDocument(InputStream is) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
    DOMImplementationLS impl = (DOMImplementationLS)registry.getDOMImplementation("LS");
    LSParser parser = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
    // we need to ignore whitespace here so the nodeToString() method will be able to indent it properly:
    parser.setFilter(new IgnoreWhitespaceFilter());
    LSInput domInput = impl.createLSInput();
    domInput.setByteStream(is);
    return parser.parse(domInput);
  }

  private String nodeToString(Node node) {
    StringWriter sw = new StringWriter();
    try {
      Transformer t = TransformerFactory.newInstance().newTransformer();
      t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Check the filenames listed in the message and grep them for the exact rule id to see if it exists.
  2. Correct the rule id spelling and case to match the rulegroup @id attribute in the XML.
  3. Confirm you pass the correct Language so the right set of grammar files is searched.
  4. If the rule was removed/renamed in an upgrade, update to the new id or pin your LanguageTool version.

Example fix

// before
String xml = creator.toXML(new RuleId("UPPERCASE_I"), new English());
// after
String xml = creator.toXML(new RuleId("UPPERCASE_SENTENCE_START"), new English()); // use exact @id
Defensive patterns

Strategy: validation

Validate before calling

// verify the id exists in the language's grammar files before calling
boolean exists = grammarFiles.stream()
    .anyMatch(f -> fileContent(f).contains("rulegroup id=\"" + ruleId.getId() + "\""));
if (!exists) throw new IllegalArgumentException("Unknown rule id: " + ruleId.getId());

Try / catch

try {
  xml = creator.toXML(ruleId, language);
} catch (RuntimeException e) {
  logger.warn("Rule not found: " + ruleId.getId() + " (" + e.getMessage() + ")");
}

Prevention

When it happens

Trigger: toXML(ruleId, language) where /rules/category/rulegroup[@id='...'] matches no node in any file, including test testToXMLInvalidRuleId and the xml() helper.

Common situations: Typo in the rule id; rule exists in a different language's file; rule was renamed/removed in a LanguageTool upgrade; passing the rulegroup name vs. category vs. rule id inconsistently; case-sensitivity mismatch in ids.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — 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/6f2a038eab92bc4c. Report an issue: GitHub.