{"record":{"id":"d6647287727b26e5","repo":"languagetool-org/languagetool","slug":"minoccurrences-must-be-0-or-1-i","errorCode":null,"errorMessage":"minOccurrences must be 0 or 1: ${i}","messagePattern":"minOccurrences must be 0 or 1: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternToken.java","lineNumber":415,"sourceCode":"  }\n\n  /**\n   * @param i exception scope length.\n   */\n  public void setSkipNext(int i) {\n    if (i < -1 || i > Byte.MAX_VALUE) {\n      throw new IllegalArgumentException(\"'skip' should be between -1 and \" + Byte.MAX_VALUE);\n    }\n    skip = (byte) i;\n  }\n\n  /**\n   * The minimum number of times this element may occur.\n   * @param i currently only {@code 0} and {@code 1} are supported\n   */\n  public void setMinOccurrence(int i) {\n    if (i != 0 && i != 1) {\n      throw new IllegalArgumentException(\"minOccurrences must be 0 or 1: \" + i);\n    }\n    setFlag(MAY_BE_OMITTED_MASK, i == 0);\n  }\n\n  /**\n   * The maximum number of times this element may occur.\n   * @param i a number &gt;= 1 or {@code -1} for unlimited occurrences\n   */\n  public void setMaxOccurrence(int i) {\n    if (i == 0) {\n      throw new IllegalArgumentException(\"maxOccurrences may not be 0\");\n    }\n    if (i < -1 || i > Byte.MAX_VALUE) {\n      throw new IllegalArgumentException(\"maxOccurrences should be between -1 and \" + Byte.MAX_VALUE + \" but was: \" + i);\n    }\n    maxOccurrence = (byte) i;\n  }\n","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternToken.java#L397-L433","documentation":"PatternToken.setMinOccurrence(int) only accepts 0 or 1: the minimum-occurrence feature ('token may be omitted') is limited to a boolean-like choice, enforced by the MAY_BE_OMITTED_MASK flag. Any other value throws IllegalArgumentException. Higher minimums are not supported by this API.","triggerScenarios":"Calling setMinOccurrence(2) or any value other than 0/1, directly or through PatternRuleBuilder/build() when parsing minOccurs attributes from rule XML (see testTwoZeroMinOccurrences).","commonSituations":"Rule authors writing minOccurs=\"2\" expecting repetition support; programmatic builders translating generic quantifier semantics (min>1) into PatternToken; code generator emitting min counts from grammar specs.","solutions":["Restrict the value to 0 (may be omitted) or 1 (required) before calling.","For min>1 repetition, model it differently: use setMaxOccurrence with multiple token elements or restructure the rule pattern.","If parsing XML, map minOccurs>1 to repeated <token> elements or reject the rule at load time with a clear message.","Update to a LanguageTool version if newer semantics are needed, after checking the changelog."],"exampleFix":"// before\npToken.setMinOccurrence(2);\n// after\npToken.setMinOccurrence(1); // use 0 or 1 only; express min>1 via repeated tokens","handlingStrategy":"validation","validationCode":"if (minOccurrence != 0 && minOccurrence != 1) {\n  throw new IllegalArgumentException(\"PatternToken supports min 0 or 1 only, got: \" + minOccurrence);\n}\npToken.setMinOccurrence(minOccurrence);","typeGuard":"boolean isBoolLike(int i) { return i == 0 || i == 1; }","tryCatchPattern":"try {\n  token.setMinOccurrence(min);\n} catch (IllegalArgumentException e) {\n  token.setMinOccurrence(1); // treat as required; log the unsupported config\n}","preventionTips":["Treat minOccurrence as a boolean (omitted vs required), not a count.","Express min>1 repetition with repeated token elements instead.","Reject minOccurs>1 in rule XML at load time with a clear message.","Map generic quantifier specs to LanguageTool's limited semantics explicitly."],"tags":["validation","unsupported-value","java"],"backgroundTag":"invalid-argument-value","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"}