mikefarah/yq · error
cannot encode %v to XML - only maps can be encoded
Error message
cannot encode %v to XML - only maps can be encoded
What it means
The XML encoder's top-level Encode only supports mapping nodes (and bare scalars as character data); anything else — a top-level sequence, alias, or other kind — is rejected with this message. XML documents need a root element, which only a map can provide.
Source
Thrown at pkg/yqlib/encoder_xml.go:95
return err
}
}
switch node.Kind {
case MappingNode:
err := e.encodeTopLevelMap(encoder, node)
if err != nil {
return err
}
case ScalarNode:
var charData xml.CharData = []byte(node.Value)
err := encoder.EncodeToken(charData)
if err != nil {
return err
}
return encoder.Flush()
default:
return fmt.Errorf("cannot encode %v to XML - only maps can be encoded", node.Tag)
}
return encoder.EncodeToken(newLine)
}
func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *CandidateNode) error {
err := e.encodeComment(encoder, headAndLineComment(node))
if err != nil {
return err
}
for i := 0; i < len(node.Content); i += 2 {
key := node.Content[i]
value := node.Content[i+1]
start := xml.StartElement{Name: xml.Name{Local: key.Value}}
log.Debugf("comments of key %v", key.Value)
err := e.encodeComment(encoder, headAndLineComment(key))View on GitHub (pinned to 8b5af0694b)
Solutions
- Wrap the array in a map, e.g. `yq -o xml '{items: .}'` so there is a root element.
- Select a specific map from the sequence: `yq -o xml '.[0]'`.
- Use an expression that returns a single object rather than all(...)/[...] results.
- If lists are expected, restructure the source data so the root is an object with an array field.
Example fix
// before
yq -o xml '.' list.yaml # root is an array
// after
yq -o xml '{items: .}' list.yaml Defensive patterns
Strategy: validation
Validate before calling
yq 'kind' file.yaml # must be "map" (or "scalar") for -o xml
Type guard
// shell
[ "$(yq 'kind' doc.yaml)" = "map" ] || yq -o xml '{root: .}' doc.yaml Try / catch
// Go
if err := xmlEnc.Encode(w, node); err != nil {
if strings.Contains(err.Error(), "only maps can be encoded") {
// wrap sequence in a map: {items: node} and retry
}
} Prevention
- Ensure a single root object exists before XML output
- Wrap sequences explicitly: `{items: .}`
- Avoid all()/select expressions that return bare sequences as the final result
When it happens
Trigger: Running `yq -o xml '.' file.yaml` where the root document is an array (e.g. `- a\n- b`) or an alias node instead of a map.
Common situations: Converting YAML/JSON arrays (lists of records) directly to XML; output of a select/all() expression that returns a sequence; XML round-trips where the document root was an array of repeated elements.
Related errors
- cannot use %v as attribute, only scalars are supported
- cannot encode %v as URI, can only operate on strings. Please
- cannot encode %v as URI, can only operate on strings. Please
- unsupported type %v
- no support for output format
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/73fb1733046364aa.
Report an issue: GitHub.