{"record":{"id":"9c9e0b34dfb4c7fd","repo":"languagetool-org/languagetool","slug":"id-is-null-for-rule-with-name","errorCode":null,"errorMessage":"id is null for rule with name '","messagePattern":"id is null for rule with name '","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java","lineNumber":235,"sourceCode":"          if (YES.equals(premiumFileAttribute)) {\n            isPremiumRule = true;\n          } else if (NO.equals(premiumFileAttribute)) {\n            isPremiumRule = false;\n          }\n        } else {\n          isPremiumRule = false;\n        }\n        if (inRuleGroup) {\n          subId++;\n          if (id == null) {\n            id = ruleGroupId;\n          }\n          if (name == null) {\n            name = ruleGroupDescription;\n          }\n        }\n        if (id == null && !relaxedMode) {\n          throw new RuntimeException(\"id is null for rule with name '\" + name + \"'\");\n        }\n        id = idPrefix != null ? idPrefix + id : id;\n        if (inRuleGroup && ruleGroupDefaultOff && attrs.getValue(DEFAULT) != null) {\n          throw new RuntimeException(\"Rule group \" + ruleGroupId + \" is off by default, thus a subrule of \" + id + \" cannot specify 'default=...'. \\033[1m Remove 'default=...' from rule group or subrule level in \" + ruleGroupId + \"!\\033[0m\");\n        }\n        if (inRuleGroup && ruleGroupDefaultTempOff && attrs.getValue(DEFAULT) != null) {\n          throw new RuntimeException(\"Rule group \" + ruleGroupId + \" is off by default, thus a subrule of \" + id + \" cannot specify 'default=...'. \\033[1m Remove 'default=...' from rule group or subrule level in \" + ruleGroupId + \"!\\033[0m\");\n        }\n        if (inRuleGroup && ruleGroupDefaultOff) {\n          defaultOff = true;\n        } else if (inRuleGroup && ruleGroupDefaultTempOff) {\n          defaultTempOff = true;\n        } else {\n          defaultOff = OFF.equals(attrs.getValue(DEFAULT));\n          defaultTempOff = TEMP_OFF.equals(attrs.getValue(DEFAULT));\n        }\n        correctExamples = new ArrayList<>();\n        antipatternExamples = new ArrayList<>();","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java#L217-L253","documentation":"PatternRuleHandler parses LanguageTool XML grammar rule files with a SAX handler. Every <rule> must carry an 'id' attribute unless the parser is in relaxedMode; this RuntimeException fires when a rule element ends without an id. Ids are required to reference, enable/disable, and deduplicate rules.","triggerScenarios":"Parsing a grammar XML where a <rule> element (or its <rulegroup>) lacks an id attribute while relaxedMode is false. Occurs via PatternRuleLoader.parse(...) or JLanguageTool rule loading.","commonSituations":"Hand-written or edited custom rule XML missing id=\"...\"; XML where rulegroup-level id inheritance was expected but the rule itself needs one; merging rule files that dropped attributes.","solutions":["Add an id attribute to the offending <rule> element in the XML file","If the rule sits in a <rulegroup>, ensure the group has an id and the rule has its own unique sub-id (or set one)","If parsing third-party/incomplete XML intentionally, enable relaxedMode on the loader so ids are auto-derived"],"exampleFix":"// before\n<rule>\n  <pattern>...</pattern>\n</rule>\n// after\n<rule id=\"MY_RULE_ID\" name=\"my rule\">\n  <pattern>...</pattern>\n</rule>","handlingStrategy":"validation","validationCode":"// Before loading: sanity-check rule XML for ids\nDocument doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(ruleXml);\nNodeList rules = doc.getElementsByTagName(\"rule\");\nfor (int i = 0; i < rules.getLength(); i++) {\n  if (rules.item(i).getAttributes().getNamedItem(\"id\") == null)\n    throw new IllegalStateException(\"rule missing id at index \" + i);\n}","typeGuard":null,"tryCatchPattern":"try { loader.parse(ruleXml, \"en\"); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"id is null\")) { log.error(\"Fix rule XML: add id attribute\"); } throw e; }","preventionTips":["Always give every <rule> an id and name","Run the rule XML through a schema/DTD check before loading","Keep template files with id placeholders that fail loudly if unfilled"],"tags":["xml","rules","parsing","languagetool"],"backgroundTag":"missing-required-argument","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}