languagetool-org/languagetool · error · RuntimeException
Could not parse URL for rule
Error message
Could not parse URL for rule: ${rule}: '${urlForRuleGroup}' What it means
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.
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
Example fix
// before <rulegroup id="G" url="wiki page"> // after <rulegroup id="G" url="https://example.com/wiki/page">
Defensive patterns
Strategy: validation
Validate before calling
// Validate rulegroup-level url attributes before loading
NodeList groups = doc.getElementsByTagName("rulegroup");
for (int i = 0; i < groups.getLength(); i++) {
Node u = groups.item(i).getAttributes().getNamedItem("url");
if (u != null) new java.net.URL(u.getNodeValue());
} Try / catch
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; } Prevention
- 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
When it happens
Trigger: A <rule> with no url attribute inside a <rulegroup url="..."> where the group URL fails java.net.URL parsing.
Common situations: 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.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Could not parse URL for rule:
- s can only contain s without errors (i.e. no…
- Cannot activate rule '
- id is null for rule with name '
- MalformedURLException for decommunization URL
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/f163e6c437cfbc73.
Report an issue: GitHub.
Appendix: source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java:924
}
if (defaultOff) {
rule.setDefaultOff();
}
if (defaultTempOff) {
rule.setDefaultTempOff();
}
if (url != null && url.length() > 0) {
try {
String s = url.toString();
rule.setUrl(internUrl(s));
} catch (MalformedURLException e) {
throw new RuntimeException("Could not parse URL for rule: " + rule + ": '" + url + "'", e);
}
} else if (urlForRuleGroup != null && urlForRuleGroup.length() > 0) {
try {
rule.setUrl(internUrl(urlForRuleGroup.toString()));
} catch (MalformedURLException e) {
throw new RuntimeException("Could not parse URL for rule: " + rule + ": '" + urlForRuleGroup + "'", e);
}
}
// inheritance of values - if no type value is defined for a rule, take the rule group's value etc:
if (ruleIssueType != null) {
rule.setLocQualityIssueType(ITSIssueType.getIssueType(ruleIssueType));
} else if (ruleGroupIssueType != null) {
rule.setLocQualityIssueType(ITSIssueType.getIssueType(ruleGroupIssueType));
} else if (categoryIssueType != null) {
rule.setLocQualityIssueType(ITSIssueType.getIssueType(categoryIssueType));
}
int prio = 0;
if (prioCategoryAttribute != 0) {
prio = prioCategoryAttribute;
}
if (prioRuleGroupAttribute != 0) {
prio = prioRuleGroupAttribute;
}
if (prioRuleAttribute != 0) {View on GitHub (pinned to 2e990059ce)