languagetool-org/languagetool · error · RuntimeException
Could not turn rule '${ruleId}' for language ${language} int
Error message
Could not turn rule '${ruleId}' for language ${language} into a string What it means
PatternRuleXmlCreator.toXML() extracts a rulegroup node from the language's rule XML files via XPath and wraps any exception during that conversion in a RuntimeException('Could not turn rule ... into a string'). This branch fires when the files could be searched but serialization/XPath evaluation threw; if nothing throws but no node matches, error 94 is thrown instead.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleXmlCreator.java:76
return nodeToString(ruleNodeInGroup);
}
if (ruleId.getSubId() != null) {
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();View on GitHub (pinned to 2e990059ce)
Solutions
- Inspect e.getCause() to find whether parsing or XPath evaluation failed, and fix that specific document/environment issue.
- Ensure the rule id contains only plain characters usable inside an XPath predicate (escape or avoid quotes/apostrophes).
- Verify the grammar XML files for the language parse correctly (validate with an XML tool).
- Ensure the runtime supports the DOM Level 3 Load/Save implementation (not a stripped JRE/GraalVM without it).
Example fix
// before
String xml = creator.toXML(new RuleId("it's-rule"), lang);
// after
String xml = creator.toXML(new RuleId("its-rule"), lang); // avoid quotes in rule ids Defensive patterns
Strategy: try-catch
Validate before calling
// check id is XPath-predicate-safe
if (ruleId.getId().matches(".*['\[\]].*")) throw new IllegalArgumentException("Unsafe rule id: " + ruleId.getId()); Try / catch
try {
xml = creator.toXML(ruleId, language);
} catch (RuntimeException e) {
logger.warn("XML conversion failed for " + ruleId + ": " + e.getCause());
} Prevention
- Keep rule ids free of quotes and XPath special characters.
- Run on a JVM with full DOM Level 3 Load/Save support (avoid stripped runtimes).
- Validate grammar XML files parse cleanly before conversion.
- Read the chained cause to distinguish parse vs. XPath failures.
When it happens
Trigger: Calling toXML(RuleId, Language) when XPath evaluation, document parsing (getDocument), or nodeToString throws for a rule whose id exists in filenames.
Common situations: Rule id containing characters that break the XPath string query (quotes/brackets); DOM configuration issues (DOMImplementationRegistry failing in restricted environments like applets/GraalVM); malformed rule XML documents in the grammar directory.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- Cannot load or parse input stream of '${filename}'
- Could not find rule '${ruleId}' for language ${language} in
- WrongParameterNumberException
- listUnknownWords is set to false, unknown words not stored
- Unknown mode: <mode>
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/18ac35e8830f18a0.
Report an issue: GitHub.