{"record":{"id":"f78a78049195ab1e","repo":"apache/maven","slug":"expected-root-element-roottag-but-found","errorCode":null,"errorMessage":"Expected root element '${rootTag}' but found '{}'","messagePattern":"Expected root element '(.+?)' but found '(.+?)'","errorType":"exception","errorClass":"XMLStreamException","httpStatus":null,"severity":"error","filePath":"src/mdo/reader-stax.vm","lineNumber":276,"sourceCode":"     * @throws XMLStreamException XMLStreamException if\n     * any.\n     * @return ${root.name}\n     */\n#if ( $locationTracking )\n    public ${root.name} read(XMLStreamReader parser, boolean strict, InputSource inputSrc) throws XMLStreamException {\n#else\n    public ${root.name} read(XMLStreamReader parser, boolean strict) throws XMLStreamException {\n#end\n#if ( $needXmlContext )\n        Deque<Object> context = new ArrayDeque<>();\n#end\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.getName() + \"'\", 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#if ( $locationTracking )\n                $rootLcapName = parse${rootUcapName}(parser, strict, parser.getNamespaceURI(), inputSrc);\n#elseif ( $needXmlContext )\n                $rootLcapName = parse${rootUcapName}(parser, strict, parser.getNamespaceURI(), context);\n#else\n                $rootLcapName = parse${rootUcapName}(parser, strict, parser.getNamespaceURI());\n#end\n                parsed = true;\n            }\n            eventType = parser.next();\n        }\n        if (parsed) {\n            return $rootLcapName;\n        }","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/src/mdo/reader-stax.vm#L258-L294","documentation":"Thrown by the STAX reader that modello generates from reader-stax.vm (the template behind readers like MavenXpp3Reader). In read(XMLStreamReader, strict), the first START_ELEMENT's local name must equal the model's root tag (the ${rootTag} placeholder, e.g. 'project' for the POM model); with strict=true any other name aborts the parse and the message reports the element actually found (as a QName, via parser.getName()). It is the reader's first guard against handing a model-specific parser the wrong kind of XML document.","triggerScenarios":"Calling read(InputStream/Reader, true) or read(XMLStreamReader, true) on a document whose root element is not the model's root tag: passing settings.xml or maven-metadata.xml to a POM reader, passing a fragment such as <modules> or <dependency> instead of a full document, or a root with the right namespace but a different local name.","commonSituations":"Routing mixed XML file types through one generated reader; using a reader built from a model version whose root tag changed; feeding POM snippets copied without the <project> wrapper; pipelines passing the wrong variable to read().","solutions":["Verify the input is the document type this reader was generated for and that its root element matches the expected root tag (e.g. <project> for a pom).","Use the reader matching the document: SettingsXpp3Reader for settings.xml, MetadataXpp3Reader for maven-metadata.xml, MavenXpp3Reader for pom.xml.","Peek the root element local name before calling read() and branch to the correct reader.","Only if lenient reading is acceptable, call read(parser, false) - the root-name check is skipped in non-strict mode."],"exampleFix":"// before\nModel model = new MavenXpp3Reader().read(in, true);\n// in actually held settings.xml -> Expected root element 'project' but found '<settings>'\n\n// after\nbyte[] bytes = in.readAllBytes();\nString root = peekRootLocalName(new ByteArrayInputStream(bytes));\nif (!\"project\".equals(root)) {\n    throw new IllegalArgumentException(\"Not a pom document, root element: \" + root);\n}\nModel model = new MavenXpp3Reader().read(new ByteArrayInputStream(bytes), true);","handlingStrategy":"validation","validationCode":"byte[] bytes = in.readAllBytes();\nXMLInputFactory f = XMLInputFactory.newFactory();\nf.setProperty(XMLInputFactory.SUPPORT_DTD, false);\nXMLStreamReader peek = f.createXMLStreamReader(new ByteArrayInputStream(bytes));\nString root = null;\nwhile (peek.hasNext()) {\n    if (peek.next() == XMLStreamReader.START_ELEMENT) { root = peek.getLocalName(); break; }\n}\npeek.close();\nif (!\"project\".equals(root)) {\n    throw new IllegalArgumentException(\"Not a pom document, root element: \" + root);\n}\nModel model = new MavenXpp3Reader().read(new ByteArrayInputStream(bytes), true);","typeGuard":"static boolean isRootElementMismatch(XMLStreamException e) {\n    return e.getMessage() != null && e.getMessage().startsWith(\"Expected root element\");\n}","tryCatchPattern":"try {\n    Model model = reader.read(parser, true);\n} catch (XMLStreamException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Expected root element\")) {\n        throw new IllegalArgumentException(\"Wrong document type for this reader: \" + e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Route each XML document type to the reader generated for its model (pom vs settings vs metadata).","Peek the root element local name before handing any document to a model reader.","Keep model definitions, generated readers, and documents on matching versions.","Log the offending root name from the exception message to spot misrouted files."],"tags":["xml","stax","modello","strict-mode","root-element","parsing"],"backgroundTag":"xml-root-element-mismatch","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}