{"id":"32d333034a560765","repo":"gohugoio/hugo","slug":"failed-to-unmarshal-xml-w","errorCode":null,"errorMessage":"failed to unmarshal XML: %w","messagePattern":"failed to unmarshal XML: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"parser/metadecoders/decoder.go","lineNumber":294,"sourceCode":"\n// UnmarshalTo unmarshals data in format f into v.\nfunc (d Decoder) UnmarshalTo(data []byte, f Format, v any) error {\n\tvar err error\n\n\tswitch f {\n\tcase ORG:\n\t\terr = d.unmarshalORG(data, v)\n\tcase JSON:\n\t\terr = json.Unmarshal(data, v)\n\tcase XML:\n\t\tvar xmlRoot xml.Map\n\t\txmlRoot, err = xml.NewMapXml(data)\n\n\t\tvar xmlValue map[string]any\n\t\tif err == nil {\n\t\t\txmlRootName, err := xmlRoot.Root()\n\t\t\tif err != nil {\n\t\t\t\treturn toFileError(f, data, fmt.Errorf(\"failed to unmarshal XML: %w\", err))\n\t\t\t}\n\n\t\t\t// Get the root value and verify it's a map\n\t\t\trootValue := xmlRoot[xmlRootName]\n\t\t\tif rootValue == nil {\n\t\t\t\treturn toFileError(f, data, fmt.Errorf(\"XML root element '%s' has no value\", xmlRootName))\n\t\t\t}\n\n\t\t\t// Type check before conversion\n\t\t\tmapValue, ok := rootValue.(map[string]any)\n\t\t\tif !ok {\n\t\t\t\treturn toFileError(f, data, fmt.Errorf(\"XML root element '%s' must be a map/object, got %T\", xmlRootName, rootValue))\n\t\t\t}\n\t\t\txmlValue = mapValue\n\t\t}\n\n\t\tswitch v := v.(type) {\n\t\tcase *map[string]any:","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/parser/metadecoders/decoder.go#L276-L312","documentation":"When unmarshaling XML data (data files or transform.Unmarshal), Hugo parses the document into a map with mxj (xml.NewMapXml) and then asks for the root element name via xmlRoot.Root(). This error wraps the failure of that Root() call — the parsed result has no identifiable single root element, typically because the document is empty or malformed at the top level.","triggerScenarios":"Calling `transform.Unmarshal` on an XML string, or loading a `.xml` data file, where xml.NewMapXml succeeded (or returned partial data) but Root() errors — e.g. an empty document, only an XML declaration/comments with no element, or content that yields no root key in the map.","commonSituations":"Fetching a remote feed with `resources.GetRemote` that returns an empty body or an HTML error page and piping it into transform.Unmarshal; truncated XML files from failed downloads; data files accidentally saved empty.","solutions":["Inspect the actual XML content being parsed (the wrapped mxj error and the file context in the error output identify it) and ensure it contains exactly one root element.","For remote data, check the response before unmarshaling: verify `.Err` and status on the GetRemote resource and guard against empty `.Content`.","Validate the file with an XML linter (`xmllint --noout file.xml`) and fix the malformation or re-download the truncated file."],"exampleFix":"{{/* before */}}\n{{ $data := resources.GetRemote $url | transform.Unmarshal }}\n\n{{/* after */}}\n{{ $r := resources.GetRemote $url }}\n{{ if $r.Err }}{{ errorf \"fetch failed: %s\" $r.Err }}\n{{ else if not $r.Content }}{{ errorf \"empty response from %s\" $url }}\n{{ else }}{{ $data := $r | transform.Unmarshal }}{{ end }}","handlingStrategy":"validation","validationCode":"// Well-formedness check before handing XML to Hugo\nd := xml.NewDecoder(bytes.NewReader(data))\nfor { if _, err := d.Token(); err == io.EOF { break } else if err != nil { return fmt.Errorf(\"bad XML: %w\", err) } }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to unmarshal XML\") {\n    // wraps the parser error — inspect errors.Unwrap(err) for line/position info\n}","preventionTips":["Validate feeds/XML with xmllint or encoding/xml in your ingest pipeline before placing them in data/","Ensure correct encoding declarations and escaped entities (&amp;) in generated XML","For remote XML (resources.GetRemote), check the HTTP status and content-type before Unmarshal"],"tags":["hugo","xml","unmarshal","data-files","remote-resources"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}