{"record":{"id":"f163e6c437cfbc73","repo":"languagetool-org/languagetool","slug":"could-not-parse-url-for-rule-rule-urlforru","errorCode":null,"errorMessage":"Could not parse URL for rule: ${rule}: '${urlForRuleGroup}'","messagePattern":"Could not parse URL for rule: (.+?): '(.+?)'","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java","lineNumber":924,"sourceCode":"    }\n    if (defaultOff) {\n      rule.setDefaultOff();\n    }\n    if (defaultTempOff) {\n      rule.setDefaultTempOff();\n    }\n    if (url != null && url.length() > 0) {\n      try {\n        String s = url.toString();\n        rule.setUrl(internUrl(s));\n      } catch (MalformedURLException e) {\n        throw new RuntimeException(\"Could not parse URL for rule: \" + rule + \": '\" + url + \"'\", e);\n      }\n    } else if (urlForRuleGroup != null && urlForRuleGroup.length() > 0) {\n      try {\n        rule.setUrl(internUrl(urlForRuleGroup.toString()));\n      } catch (MalformedURLException e) {\n        throw new RuntimeException(\"Could not parse URL for rule: \" + rule + \": '\" + urlForRuleGroup + \"'\", e);\n      }\n    }\n    // inheritance of values - if no type value is defined for a rule, take the rule group's value etc:\n    if (ruleIssueType != null) {\n      rule.setLocQualityIssueType(ITSIssueType.getIssueType(ruleIssueType));\n    } else if (ruleGroupIssueType != null) {\n      rule.setLocQualityIssueType(ITSIssueType.getIssueType(ruleGroupIssueType));\n    } else if (categoryIssueType != null) {\n      rule.setLocQualityIssueType(ITSIssueType.getIssueType(categoryIssueType));\n    }\n    int prio = 0;\n    if (prioCategoryAttribute != 0) {\n      prio = prioCategoryAttribute;\n    }\n    if (prioRuleGroupAttribute != 0) {\n      prio = prioRuleGroupAttribute;\n    }\n    if (prioRuleAttribute != 0) {","sourceCodeStart":906,"sourceCodeEnd":942,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java#L906-L942","documentation":"Same URL guard but for the rule-group-level url: when a rule defines no url of its own, urlForRuleGroup is inherited and parsed. If that inherited value is malformed, prepareRule throws this RuntimeException naming the rule and the group URL.","triggerScenarios":"A <rule> with no url attribute inside a <rulegroup url=\"...\"> where the group URL fails java.net.URL parsing.","commonSituations":"Group-level URL written without scheme or with illegal characters; several rules failing at once because one bad group URL is inherited by every subrule.","solutions":["Fix the url attribute on the <rulegroup> element (add scheme / encode characters)","Or give the rule its own valid url attribute to override the broken inherited one","Remove the group url attribute if the link is obsolete"],"exampleFix":"// before\n<rulegroup id=\"G\" url=\"wiki page\">\n// after\n<rulegroup id=\"G\" url=\"https://example.com/wiki/page\">","handlingStrategy":"validation","validationCode":"// Validate rulegroup-level url attributes before loading\nNodeList groups = doc.getElementsByTagName(\"rulegroup\");\nfor (int i = 0; i < groups.getLength(); i++) {\n  Node u = groups.item(i).getAttributes().getNamedItem(\"url\");\n  if (u != null) new java.net.URL(u.getNodeValue());\n}","typeGuard":null,"tryCatchPattern":"try { loader.parse(ruleXml, lang); } catch (RuntimeException e) { if (e.getMessage().contains(\"Could not parse URL for rule\")) { log.error(\"Fix rulegroup url attribute\"); } throw e; }","preventionTips":["Fix group-level urls first — one bad value breaks every subrule","Give rules explicit urls if they must not inherit the group url","Validate both rule and rulegroup url attributes in a pre-load lint step"],"tags":["xml","url","malformed-url","languagetool"],"backgroundTag":"invalid-url-format","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"}