{"record":{"id":"212800c756258e08","repo":"apache/maven","slug":"duplicated-tag-roottag-212800","errorCode":null,"errorMessage":"Duplicated tag: '${rootTag}'","messagePattern":"Duplicated tag: '(.+?)'","errorType":"exception","errorClass":"XMLStreamException","httpStatus":null,"severity":"error","filePath":"src/mdo/reader.vm","lineNumber":445,"sourceCode":"     *\n     * @param parser a parser object.\n     * @param strict a strict object.\n     * @throws IOException IOException if any.\n     * @throws XMLStreamException XMLStreamException if\n     * any.\n     * @return ${root.name}\n     */\n    public ${root.name} read(XMLStreamReader parser, boolean strict) throws IOException, XMLStreamException {\n        $rootUcapName $rootLcapName = null;\n        int eventType = parser.getEventType();\n        boolean parsed = false;\n        while (eventType != XMLStreamReader.END_DOCUMENT) {\n            if (eventType == XMLStreamReader.START_ELEMENT) {\n                if (strict && ! \"${rootTag}\".equals(parser.getLocalName())) {\n                    throw new XMLStreamException(\"Expected root element '${rootTag}' but found '\" + parser.getLocalName() + \"'\", parser.getLocation(), null);\n                } else if (parsed) {\n                    // fallback, already expected a XMLStreamException due to invalid XML\n                    throw new XMLStreamException(\"Duplicated tag: '${rootTag}'\", parser.getLocation(), null);\n                }\n                $rootLcapName = parse${rootUcapName}(parser, strict);\n                parsed = true;\n            }\n            eventType = parser.next();\n        }\n        if (parsed) {\n            return $rootLcapName;\n        }\n        throw new XMLStreamException(\"Expected root element '${rootTag}' but found no element at all: invalid XML document\", parser.getLocation(), null);\n    } //-- ${root.name} read(XMLStreamReader, boolean)\n\n#foreach ( $class in $model.allClasses )\n #if ( $class.name != \"InputSource\" && $class.name != \"InputLocation\" )\n  #set ( $classUcapName = $Helper.capitalise( $class.name ) )\n  #set ( $classLcapName = $Helper.uncapitalise( $class.name ) )\n  #set ( $ancestors = $Helper.ancestors( $class ) )\n  #set ( $allFields = [] )","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/src/mdo/reader.vm#L427-L463","documentation":"Identical to the modern template's guard: after one root element has been parsed, the read loop continues to END_DOCUMENT, and a second top-level START_ELEMENT triggers this duplicate-root fallback. Well-formed XML cannot have two roots, so this surfaces mainly with lenient/custom STAX parsers or concatenated-document streams that present the second root as an event.","triggerScenarios":"read() over a stream with two concatenated XML documents; lenient XMLStreamReader implementations that do not enforce single-root well-formedness; strict=false reads where a second top-level element follows the first parsed root.","commonSituations":"Test fixtures joining several XML snippets; CI outputs flushing multiple documents into one stream; appended/truncated files repaired by concatenation.","solutions":["Make the input a single well-formed document - wrap or split the content.","Split concatenated documents on each <?xml declaration and parse each with its own reader.","Pre-validate with a standard STAX parser to fail early on multi-root input."],"exampleFix":"// before: one InputStream holding two concatenated pom documents\nreader.read(in, true); // throws Duplicated tag: 'project'\n\n// after: split documents, parse each separately\nfor (byte[] doc : splitXmlDocuments(in)) {\n    Model model = reader.read(new ByteArrayInputStream(doc), true);\n}","handlingStrategy":"try-catch","validationCode":"// Pre-scan: a standard factory itself rejects a second root during next()\nXMLInputFactory f = XMLInputFactory.newFactory();\nf.setProperty(XMLInputFactory.SUPPORT_DTD, false);\nXMLStreamReader p = f.createXMLStreamReader(new ByteArrayInputStream(bytes));\ntry {\n    while (p.hasNext()) { p.next(); } // throws on the second top-level element\n} finally {\n    p.close();\n}","typeGuard":null,"tryCatchPattern":"try {\n    Model model = reader.read(parser, true);\n} catch (XMLStreamException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Duplicated tag\")) {\n        // multiple top-level elements in the stream: fix the producer\n    }\n    throw e;\n}","preventionTips":["Never concatenate XML documents into one stream.","Wrap batches in a container element or split before parsing.","Add a well-formedness pre-check in ingestion pipelines."],"tags":["xml","stax","malformed-input","root-element","parsing"],"backgroundTag":"xml-multiple-root-elements","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}