{"record":{"id":"2a946fea43c026af","repo":"languagetool-org/languagetool","slug":"marker-may-not-be-nested-in-rule","errorCode":null,"errorMessage":"'<marker>' may not be nested in rule '","messagePattern":"'<marker>' may not be nested in rule '","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java","lineNumber":449,"sourceCode":"        if (minPrevMatchesStr2 != null) {\n          ruleGroupMinPrevMatches = Integer.parseInt(minPrevMatchesStr2);  \n        }\n        String distanceTokensStr2 = attrs.getValue(DISTANCETOKENS);\n        if (distanceTokensStr2 != null) {\n          ruleGroupDistanceTokens = Integer.parseInt(distanceTokensStr2);  \n        }\n        antipatternForRuleGroupsExamples = new ArrayList<>();\n        String prioRuleGroupAttributeValue = attrs.getValue(PRIO);\n        if (prioRuleGroupAttributeValue != null) {\n          prioRuleGroupAttribute = Integer.parseInt(prioRuleGroupAttributeValue);\n        }\n        break;\n      case MATCH:\n        setMatchElement(attrs, inSuggestion && (isSuggestionSuppressMisspelled || isRuleSuppressMisspelled));\n        break;\n      case MARKER:\n        if (inMarker) {\n          throw new IllegalStateException(\"'<marker>' may not be nested in rule '\" + id + \"'\");\n        }\n        if (inIncorrectExample) {\n          incorrectExample.append(MARKER_TAG);\n        } else if (inCorrectExample) {\n          correctExample.append(MARKER_TAG);\n        } else if (inErrorTriggerExample) {\n          errorTriggerExample.append(MARKER_TAG);\n        } else if (inPattern || inAntiPattern) {\n          startPos = tokenCounter;\n          inMarker = true;\n        }\n        break;\n      case UNIFICATION:\n        uFeature = attrs.getValue(\"feature\");\n        inUnificationDef = true;\n        break;\n      case \"equivalence\":\n        uType = attrs.getValue(TYPE);","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java#L431-L467","documentation":"LanguageTool's <marker> element marks the error span inside a pattern or example and must not be nested inside another <marker>. The SAX handler tracks inMarker and throws IllegalStateException on a second opening marker while already inside one.","triggerScenarios":"XML containing <marker>...<marker>...</marker>...</marker> within a rule pattern, suggestion, or example. Raised in startElement case MARKER when inMarker is already true.","commonSituations":"Copy-paste merging two marked spans; careless editing that wraps an existing marker in another marker; automated XML generation that emits nested markers.","solutions":["Remove the outer or inner duplicate <marker> so only one nesting level remains","Split the marked region so each span is marked once, side by side, not nested","If marking two separate tokens, use two adjacent markers at the same level (check rule semantics) or a single wider marker"],"exampleFix":"// before\n<pattern><marker><token>a</token><marker><token>b</token></marker></marker></pattern>\n// after\n<pattern><marker><token>a</token><token>b</token></marker></pattern>","handlingStrategy":"validation","validationCode":"// Reject nested markers before loading\nNodeList markers = doc.getElementsByTagName(\"marker\");\nfor (int i = 0; i < markers.getLength(); i++) {\n  if (markers.item(i).getChildNodes().getLength() > 0) {\n    NodeList kids = markers.item(i).getChildNodes();\n    for (int j = 0; j < kids.getLength(); j++)\n      if (\"marker\".equals(kids.item(j).getNodeName()))\n        throw new IllegalStateException(\"nested <marker>\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try { loader.parse(ruleXml, lang); } catch (IllegalStateException e) { if (e.getMessage().contains(\"may not be nested\")) { log.error(\"Un-nest <marker> elements\"); } throw e; }","preventionTips":["Use exactly one <marker> level per span","When marking several areas, place markers side by side, never nested","Lint XML for duplicate/nested marker tags in CI"],"tags":["xml","marker","invalid-nesting","languagetool"],"backgroundTag":"schema-validation-failed","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"}