{"record":{"id":"2f538e96a1915b43","repo":"languagetool-org/languagetool","slug":"references-cannot-be-empty-line-plocator-get","errorCode":null,"errorMessage":"References cannot be empty: \n Line: ${pLocator.getLineNumber()}, column: ${pLocator.getColumnNumber()}.","messagePattern":"References cannot be empty: \n Line: (.+?), column: (.+?)\\.","errorType":"exception","errorClass":"SAXException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/XMLRuleHandler.java","lineNumber":421,"sourceCode":"    } else if (inSuggestion) {\n      suggestionMatchesOutMsg.add(mWorker);\n      // add incorrect XML character for simplicity\n      suggestionsOutMsg.append(\"\\u0001\\\\\");\n      suggestionsOutMsg.append(attrs.getValue(\"no\"));\n      checkNumber(attrs);\n    } else if (inToken && attrs.getValue(\"no\") != null) {\n      int refNumber = Integer.parseInt(attrs.getValue(\"no\"));\n      checkRefNumber(refNumber);\n      mWorker.setTokenRef(refNumber);\n      tokenReference = mWorker;\n      elements.append('\\\\');\n      elements.append(refNumber);\n    }\n  }\n\n  private void checkNumber(Attributes attrs) throws SAXException {\n    if (StringTools.isEmpty(attrs.getValue(\"no\"))) {\n      throw new SAXException(\"References cannot be empty: \" + \"\\n Line: \"\n          + pLocator.getLineNumber() + \", column: \"\n          + pLocator.getColumnNumber() + \".\");\n    } else if (Integer.parseInt(attrs.getValue(\"no\")) < 1 && regex.length() == 0) {\n      throw new SAXException(\"References must be larger than 0: \"\n          + attrs.getValue(\"no\") + \"\\n Line: \" + pLocator.getLineNumber()\n          + \", column: \" + pLocator.getColumnNumber() + \".\");\n    }\n  }\n\n  private void checkRefNumber(int refNumber) throws SAXException {\n    if (refNumber > patternTokens.size()) {\n      throw new SAXException(\"Only backward references in match elements are possible, tried to specify token \"\n          + refNumber + \"\\n\" + \"Line: \" + pLocator.getLineNumber()\n          + \", column: \" + pLocator.getColumnNumber() + \".\");\n    }\n  }\n\n  protected void setExceptions(Attributes attrs) {","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/XMLRuleHandler.java#L403-L439","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-editing rule XML and deleting the attribute value, templating tools emitting empty attributes, XML generated with missing required fields, migrating rules between formats.","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"],"exampleFix":"// before\n<match no=\"\"/>\n// after\n<match no=\"1\" postag=\"NN\"/>","handlingStrategy":"validation","validationCode":"// Pre-validate rule XML for empty required 'no' attributes\nDocument doc = parseXml(ruleFile);\nXPath xpath = XPathFactory.newInstance().newXPath();\nNodeList bad = (NodeList) xpath.evaluate(\"//*[@no='']\", doc, XPathConstants.NODESET);\nif (bad.getLength() > 0) throw new SAXException(\"Empty 'no' attribute in \" + ruleFile);","typeGuard":"boolean hasValidNoAttr(Attributes attrs) {\n  String v = attrs.getValue(\"no\");\n  return v != null && !v.trim().isEmpty() && v.chars().allMatch(Character::isDigit);\n}","tryCatchPattern":"try {\n  loader.getRules(is, filename);\n} catch (SAXException e) {\n  if (e.getMessage().contains(\"References cannot be empty\")) {\n    log.error(\"Set the 'no' attribute at \" + e.getMessage(), e);\n  } else throw e;\n}","preventionTips":["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"],"tags":["languagetool","xml-rules","sax","validation"],"backgroundTag":"empty-required-field","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"}