gohugoio/hugo · error

XML root element '%s' must be a map/object, got %T

Error message

XML root element '%s' must be a map/object, got %T

What it means

Thrown in the XML branch of Decoder.UnmarshalTo (parser/metadecoders/decoder.go:306) when the parsed XML root element's value is not a map[string]any. Hugo expects the root to contain child elements (which mxj turns into a map); a root whose direct value is a bare string, number, or array fails this type check. The %T names the actual type.

Source

Thrown at parser/metadecoders/decoder.go:306

		xmlRoot, err = xml.NewMapXml(data)

		var xmlValue map[string]any
		if err == nil {
			xmlRootName, err := xmlRoot.Root()
			if err != nil {
				return toFileError(f, data, fmt.Errorf("failed to unmarshal XML: %w", err))
			}

			// Get the root value and verify it's a map
			rootValue := xmlRoot[xmlRootName]
			if rootValue == nil {
				return toFileError(f, data, fmt.Errorf("XML root element '%s' has no value", xmlRootName))
			}

			// Type check before conversion
			mapValue, ok := rootValue.(map[string]any)
			if !ok {
				return toFileError(f, data, fmt.Errorf("XML root element '%s' must be a map/object, got %T", xmlRootName, rootValue))
			}
			xmlValue = mapValue
		}

		switch v := v.(type) {
		case *map[string]any:
			*v = xmlValue
		case *any:
			*v = xmlValue
		}
	case TOML:
		err = toml.Unmarshal(data, v)
	case YAML:
		return UnmarshalYaml(data, v)
	case CSV:
		return d.unmarshalCSV(data, v)

	default:

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Wrap the root's value in child elements so the root maps to an object: <root><value>text</value></root>.
  2. If the data is scalar, use a different format (JSON/TOML) or parse it manually.
  3. Re-export the XML ensuring the root contains only element children.

Example fix

<!-- before -->
<root>some text</root>

<!-- after -->
<root>
  <value>some text</value>
</root>
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the XML root maps to an object (has child elements).
func xmlRootIsObjectish(data []byte) bool {
    return bytes.Count(data, []byte("</")) > 0
}

Try / catch

if err := dec.UnmarshalTo(data, metadecoders.XML, &m); err != nil {
    return fmt.Errorf("XML root must be an object: %w", err)
}

Prevention

When it happens

Trigger: An XML document like <root>just text</root> where the root's value is a string, or <root>42</root> where it is a number; a root containing a single text node rather than child elements; mxj representing a list-only root as []any.

Common situations: Treating a simple scalar XML value as a structured data file; an export tool emitting text content at the root instead of wrapping it in child elements; a feed returning a single value rather than a collection.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/7b9c9463e2d74165. Report an issue: GitHub.