{"record":{"id":"d7953299deb2b499","repo":"apache/maven","slug":"expected-root-element-roottag-but-found-d79532","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.vm","lineNumber":442,"sourceCode":"\n    /**\n     * Method read.\n     *\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 ) )","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/src/mdo/reader.vm#L424-L460","documentation":"The classic modello STAX reader template (reader.vm, without the location-tracking/context features of reader-stax.vm) emits the same strict-mode root guard: in read(XMLStreamReader, strict), the first START_ELEMENT's local name must equal the model's root tag, otherwise the parse aborts with the local name that was found (parser.getLocalName() in this variant). It protects a model-specific reader from the wrong document type.","triggerScenarios":"read(parser, true) or read(InputStream, true) on XML whose root element local name differs from the expected root tag: settings.xml fed to a POM reader, an XML fragment like <dependency>, or correct vocabulary nested at the wrong level.","commonSituations":"Mixed XML types routed through one parser; readers generated from a different model version; POM snippets copy-pasted without the <project> wrapper; the wrong file variable passed to read().","solutions":["Confirm the document type and root element match this reader's model before parsing.","Use the reader generated for the document at hand (pom vs settings vs metadata).","Peek the root local name and dispatch to the right reader.","If lenient reading is acceptable, call read(parser, false) to skip the root-name check."],"exampleFix":"// before\nModel model = new MavenXpp3Reader().read(in, true); // in held settings.xml\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}","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        // wrong document type for this reader; route elsewhere\n    }\n    throw e;\n}","preventionTips":["Dispatch documents to readers by root element name.","Always peek the root before a strict read.","Keep reader version and document vocabulary in sync."],"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"}