{"record":{"id":"6f2a038eab92bc4c","repo":"languagetool-org/languagetool","slug":"could-not-find-rule-ruleid-for-language-lan","errorCode":null,"errorMessage":"Could not find rule '${ruleId}' for language ${language} in files: ${filenames}","messagePattern":"Could not find rule '(.+?)' for language (.+?) in files: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleXmlCreator.java","lineNumber":79,"sourceCode":"          NodeList ruleGroupNodes = (NodeList) xpath.evaluate(\"/rules/category/rulegroup[@id='\" + ruleId.getId() + \"']/rule\", doc, XPathConstants.NODESET);\n          if (ruleGroupNodes != null) {\n            for (int i = 0; i < ruleGroupNodes.getLength(); i++) {\n              if (Integer.toString(i+1).equals(ruleId.getSubId())) {\n                return nodeToString(ruleGroupNodes.item(i));\n              }\n            }\n          }\n        } else {\n          Node ruleGroupNode = (Node) xpath.evaluate(\"/rules/category/rulegroup[@id='\" + ruleId.getId() + \"']\", doc, XPathConstants.NODE);\n          if (ruleGroupNode != null) {\n            return nodeToString(ruleGroupNode);\n          }\n        }\n      } catch (Exception e) {\n        throw new RuntimeException(\"Could not turn rule '\" + ruleId + \"' for language \" + language + \" into a string\", e);\n      }\n    }\n    throw new RuntimeException(\"Could not find rule '\" + ruleId + \"' for language \" + language + \" in files: \" + filenames);\n  }\n\n  private Document getDocument(InputStream is) throws InstantiationException, IllegalAccessException, ClassNotFoundException {\n    DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();\n    DOMImplementationLS impl = (DOMImplementationLS)registry.getDOMImplementation(\"LS\");\n    LSParser parser = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);\n    // we need to ignore whitespace here so the nodeToString() method will be able to indent it properly:\n    parser.setFilter(new IgnoreWhitespaceFilter());\n    LSInput domInput = impl.createLSInput();\n    domInput.setByteStream(is);\n    return parser.parse(domInput);\n  }\n\n  private String nodeToString(Node node) {\n    StringWriter sw = new StringWriter();\n    try {\n      Transformer t = TransformerFactory.newInstance().newTransformer();\n      t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, \"yes\");","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleXmlCreator.java#L61-L97","documentation":"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.","triggerScenarios":"toXML(ruleId, language) where /rules/category/rulegroup[@id='...'] matches no node in any file, including test testToXMLInvalidRuleId and the xml() helper.","commonSituations":"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.","solutions":["Check the filenames listed in the message and grep them for the exact rule id to see if it exists.","Correct the rule id spelling and case to match the rulegroup @id attribute in the XML.","Confirm you pass the correct Language so the right set of grammar files is searched.","If the rule was removed/renamed in an upgrade, update to the new id or pin your LanguageTool version."],"exampleFix":"// before\nString xml = creator.toXML(new RuleId(\"UPPERCASE_I\"), new English());\n// after\nString xml = creator.toXML(new RuleId(\"UPPERCASE_SENTENCE_START\"), new English()); // use exact @id","handlingStrategy":"validation","validationCode":"// verify the id exists in the language's grammar files before calling\nboolean exists = grammarFiles.stream()\n    .anyMatch(f -> fileContent(f).contains(\"rulegroup id=\\\"\" + ruleId.getId() + \"\\\"\"));\nif (!exists) throw new IllegalArgumentException(\"Unknown rule id: \" + ruleId.getId());","typeGuard":null,"tryCatchPattern":"try {\n  xml = creator.toXML(ruleId, language);\n} catch (RuntimeException e) {\n  logger.warn(\"Rule not found: \" + ruleId.getId() + \" (\" + e.getMessage() + \")\");\n}","preventionTips":["Copy rule ids directly from the XML @id attribute; watch case sensitivity.","Confirm the Language matches where the rule is defined.","After LanguageTool upgrades, re-check ids that may have been renamed.","Grep the grammar files listed in the message before debugging further."],"tags":["xml","rule-lookup","not-found","java"],"backgroundTag":"resource-not-found","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"}