{"record":{"id":"e8ea4a6376576411","repo":"languagetool-org/languagetool","slug":"you-cannot-set-both-chunk-and-chunk-re-for-i","errorCode":null,"errorMessage":"You cannot set both 'chunk' and 'chunk_re' for + id","messagePattern":"You cannot set both 'chunk' and 'chunk_re' for \\+ id","errorType":"validation","errorClass":"SAXException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/XMLRuleHandler.java","lineNumber":532,"sourceCode":"    tokenNegated = YES.equals(attrs.getValue(NEGATE));\n    tokenInflected = YES.equals(attrs.getValue(INFLECTED));\n    if (attrs.getValue(SKIP) != null) {\n      skipPos = Integer.parseInt(attrs.getValue(SKIP));\n    }\n    if (attrs.getValue(MIN) != null) {\n      minOccurrence = Integer.parseInt(attrs.getValue(MIN));\n    }\n    if (attrs.getValue(MAX) != null) {\n      maxOccurrence = Integer.parseInt(attrs.getValue(MAX));\n    }\n    elements = new StringBuilder();\n    if (attrs.getValue(POSTAG) != null) {\n      posToken = StringInterner.intern(attrs.getValue(POSTAG));\n      posRegExp = YES.equals(attrs.getValue(POSTAG_REGEXP));\n      posNegation = YES.equals(attrs.getValue(NEGATE_POS));\n    }\n    if (attrs.getValue(CHUNKTAG) != null && attrs.getValue(CHUNKTAG_REGEXP) != null) {\n      throw new SAXException(\"You cannot set both 'chunk' and 'chunk_re' for \" + id);\n    }\n    if (attrs.getValue(CHUNKTAG) != null) {\n      chunkTag = new ChunkTag(StringInterner.intern(attrs.getValue(CHUNKTAG)));\n    } else if (attrs.getValue(CHUNKTAG_REGEXP) != null) {\n      chunkTag = new ChunkTag(StringInterner.intern(attrs.getValue(CHUNKTAG_REGEXP)), true);\n    }\n    regExpression = YES.equals(attrs.getValue(REGEXP));\n    if (attrs.getValue(SPACEBEFORE) != null) {\n      tokenSpaceBefore = YES.equals(attrs.getValue(SPACEBEFORE));\n      tokenSpaceBeforeSet = !IGNORE.equals(attrs.getValue(SPACEBEFORE));\n    }\n    if (!inAndGroup && !inOrGroup) {\n      tokenCounter++;\n    }\n    if (attrs.getValue(CASE_SENSITIVE) != null) {\n      tokenLevelCaseSet = true;\n      tokenLevelCaseSensitive = YES.equals(attrs.getValue(CASE_SENSITIVE));\n    } else {","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/XMLRuleHandler.java#L514-L550","documentation":"XMLRuleHandler throws this SAXException when a token element specifies both a 'chunk' attribute and a 'chunk_re' attribute. 'chunk' matches a chunk tag literally while 'chunk_re' treats it as a regular expression; setting both is ambiguous, so rule loading fails with the rule id in the message. Pick exactly one form per token.","triggerScenarios":"Parsing a token like <token chunk=\"NP\" chunk_re=\"N.*\"/> in setToken — both CHUNKTAG and CHUNKTAG_REGEXP attribute values are non-null and the handler throws before building the ChunkTag.","commonSituations":"Migrating rules where one attribute was added without removing the other; copy-paste from two rule examples; templated rule generation merging both options.","solutions":["Delete one of the two attributes — keep 'chunk' for literal matching or 'chunk_re' for regex","If you need alternation, express it in chunk_re (e.g. chunk_re=\"NP|PP\") rather than combining attributes","Add a schema/lint check in CI for tokens carrying both attributes"],"exampleFix":"// before\n<token chunk=\"NP\" chunk_re=\"N.*\"/>\n// after\n<token chunk_re=\"N.*\"/>","handlingStrategy":"validation","validationCode":"// Pre-parse check\nNodeList tokens = doc.getElementsByTagName(\"token\");\nfor (int i = 0; i < tokens.getLength(); i++) {\n  Element t = (Element) tokens.item(i);\n  if (t.hasAttribute(\"chunk\") && t.hasAttribute(\"chunk_re\")) {\n    throw new IllegalArgumentException(\"Token \" + i + \" sets both chunk and chunk_re\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  loader.getRules(is, filename);\n} catch (SAXException e) {\n  if (e.getMessage().startsWith(\"You cannot set both 'chunk' and 'chunk_re'\")) {\n    log.error(\"Keep only one of chunk/chunk_re per token\", e);\n  } else throw e;\n}","preventionTips":["Set exactly one of chunk / chunk_re per token","Use chunk_re alone when alternation is needed","Lint rule XML before committing"],"tags":["languagetool","xml-rules","validation","mutually-exclusive"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}