languagetool-org/languagetool · error · SAXException
References cannot be empty: Line: ${pLocator.getLineNumber
Error message
References cannot be empty:
Line: ${pLocator.getLineNumber()}, column: ${pLocator.getColumnNumber()}. What it means
XMLRuleHandler.checkNumber throws this SAXException while parsing rule XML when a <match> element (or similar reference element) has an empty 'no' attribute. The 'no' attribute must contain the number of the pattern token to reference back to. The parser fails at the reported line/column so the author can locate the malformed element.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/XMLRuleHandler.java:421
} else if (inSuggestion) {
suggestionMatchesOutMsg.add(mWorker);
// add incorrect XML character for simplicity
suggestionsOutMsg.append("\u0001\\");
suggestionsOutMsg.append(attrs.getValue("no"));
checkNumber(attrs);
} else if (inToken && attrs.getValue("no") != null) {
int refNumber = Integer.parseInt(attrs.getValue("no"));
checkRefNumber(refNumber);
mWorker.setTokenRef(refNumber);
tokenReference = mWorker;
elements.append('\\');
elements.append(refNumber);
}
}
private void checkNumber(Attributes attrs) throws SAXException {
if (StringTools.isEmpty(attrs.getValue("no"))) {
throw new SAXException("References cannot be empty: " + "\n Line: "
+ pLocator.getLineNumber() + ", column: "
+ pLocator.getColumnNumber() + ".");
} else if (Integer.parseInt(attrs.getValue("no")) < 1 && regex.length() == 0) {
throw new SAXException("References must be larger than 0: "
+ attrs.getValue("no") + "\n Line: " + pLocator.getLineNumber()
+ ", column: " + pLocator.getColumnNumber() + ".");
}
}
private void checkRefNumber(int refNumber) throws SAXException {
if (refNumber > patternTokens.size()) {
throw new SAXException("Only backward references in match elements are possible, tried to specify token "
+ refNumber + "\n" + "Line: " + pLocator.getLineNumber()
+ ", column: " + pLocator.getColumnNumber() + ".");
}
}
protected void setExceptions(Attributes attrs) {View on GitHub (pinned to 2e990059ce)
Solutions
- Set the 'no' attribute to a positive integer referencing a preceding token, e.g. <match no="1"/>
- Validate the XML against the rules DTD/XSD before loading
- Lint rule XML files in CI to catch empty required attributes
Example fix
// before <match no=""/> // after <match no="1" postag="NN"/>
Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate rule XML for empty required 'no' attributes
Document doc = parseXml(ruleFile);
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList bad = (NodeList) xpath.evaluate("//*[@no='']", doc, XPathConstants.NODESET);
if (bad.getLength() > 0) throw new SAXException("Empty 'no' attribute in " + ruleFile); Type guard
boolean hasValidNoAttr(Attributes attrs) {
String v = attrs.getValue("no");
return v != null && !v.trim().isEmpty() && v.chars().allMatch(Character::isDigit);
} Try / catch
try {
loader.getRules(is, filename);
} catch (SAXException e) {
if (e.getMessage().contains("References cannot be empty")) {
log.error("Set the 'no' attribute at " + e.getMessage(), e);
} else throw e;
} Prevention
- Always set a positive integer 'no' on <match> elements
- Validate rule XML against the LanguageTool schema in CI
- Use an XML editor/IDE with schema validation when authoring rules
When it happens
Trigger: A <match no=""/> or <match/> element without a 'no' attribute is parsed by the rule XML SAX handler; StringTools.isEmpty(attrs.getValue("no")) is true and checkNumber throws.
Common situations: Hand-editing rule XML and deleting the attribute value, templating tools emitting empty attributes, XML generated with missing required fields, migrating rules between formats.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- References must be larger than 0: ${attrs.getValue("no")} L
- Only backward references in match elements are possible, tri
- You cannot set both 'chunk' and 'chunk_re' for + id
- Please set min and max attributes on the first token in the
- <antipattern>s can only contain <example>s without errors (i
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/2f538e96a1915b43.
Report an issue: GitHub.