languagetool-org/languagetool · error · RuntimeException

Could not parse URL for rule:

Error message

Could not parse URL for rule: 

What it means

A rule's url attribute (or its inherited content) must be a syntactically valid absolute URL. prepareRule calls rule.setUrl(internUrl(s)); a MalformedURLException is rethrown as this RuntimeException, keeping the original as cause.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java:918

    for (Match m : suggestionMatchesOutMsg) {
      rule.addSuggestionMatchOutMsg(m);
    }
    suggestionMatchesOutMsg.clear();
    if (category == null) {
      throw new RuntimeException("Cannot activate rule '" + id + "', it is outside of a <category>...</category>");
    }
    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) {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Add the scheme to the url attribute, e.g. https://...
  2. URL-encode spaces and special characters in the attribute value
  3. Validate the attribute with new java.net.URL(value) before shipping the XML

Example fix

// before
<rule id="X" url="example.com/docs">...</rule>
// after
<rule id="X" url="https://example.com/docs">...</rule>
Defensive patterns

Strategy: validation

Validate before calling

// Validate rule-level url attributes before loading
NodeList rules = doc.getElementsByTagName("rule");
for (int i = 0; i < rules.getLength(); i++) {
  Node u = rules.item(i).getAttributes().getNamedItem("url");
  if (u != null) new java.net.URL(u.getNodeValue()); // throws MalformedURLException early
}

Try / catch

try { loader.parse(ruleXml, lang); } catch (RuntimeException e) { if (e.getMessage().startsWith("Could not parse URL")) { log.error("Fix url attribute (add scheme, encode chars)"); } throw e; }

Prevention

When it happens

Trigger: <rule url="..."> (rule-level url takes precedence) whose value fails java.net.URL parsing during XML rule loading.

Common situations: Missing scheme ("example.com/page" instead of "https://example.com/page"); spaces or unescaped characters in the URL; malformed entities after hand-editing XML.

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


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/7be9b7cc6bc05579. Report an issue: GitHub.