mikefarah/yq · error

csv object encoding only works for arrays of flat objects (s

Error message

csv object encoding only works for arrays of flat objects (string key => string/numbers/boolean value), child[%v] is a %v

What it means

In CSV object-encoding mode every element of the root array must be a flat mapping so its values can be placed under the header columns. This error fires when a non-first child of the array is not a mapping (after the header was successfully extracted from child[0]).

Source

Thrown at pkg/yqlib/encoder_csv.go:93

	}
	return childRow

}

func (e *csvEncoder) encodeObjects(csvWriter *csv.Writer, content []*CandidateNode) error {
	headers, err := e.extractHeader(content[0])
	if err != nil {
		return nil
	}

	err = e.encodeRow(csvWriter, headers)
	if err != nil {
		return nil
	}

	for i, child := range content {
		if child.Kind != MappingNode {
			return fmt.Errorf("csv object encoding only works for arrays of flat objects (string key => string/numbers/boolean value), child[%v] is a %v", i, child.Tag)
		}
		row := e.createChildRow(child, headers)
		err = e.encodeRow(csvWriter, row)
		if err != nil {
			return err
		}

	}
	return nil
}

func (e *csvEncoder) Encode(writer io.Writer, node *CandidateNode) error {
	if node.Kind == ScalarNode {
		return writeString(writer, node.Value+"\n")
	}

	csvWriter := csv.NewWriter(writer)
	csvWriter.Comma = e.separator

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Filter to only object elements: `yq '[.[] | select(type == "!!map")]'` before `-o csv`
  2. Wrap scalars into objects: `map(select(. != null))` or `map({value: .})`
  3. Normalize the data shape upstream so all array entries are flat objects

Example fix

// before: yq -o csv '[{a:1}, null]'
// after:  yq -o csv '[.[] | select(type == "!!map")]' on input containing only objects
Defensive patterns

Strategy: validation

Validate before calling

yq '[.[] | select(type != "!!map")] | length == 0' input.yaml  # must be true for object-CSV

Type guard

func allElementsAreMaps(node *CandidateNode) bool {
  if node.Kind != SequenceNode { return false }
  for _, c := range node.Content {
    if c.Kind != MappingNode { return false }
  }
  return true
}

Try / catch

if err := enc.Encode(node); err != nil {
  if strings.Contains(err.Error(), "child[") {
    // filter non-map children then retry
  }
}

Prevention

When it happens

Trigger: `yq -o csv '[{a: 1}, "oops"]'` — child[0] yields the header, then encodeObjects hits child[1] which is a scalar, raising this error with child[1] is a !!str.

Common situations: Arrays with mixed element types (objects plus scalars/nulls); JSON data where some array entries are null; results of expressions like `.[] | select(...)` that emit heterogeneous items.

Related errors


AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05). Data as JSON: /api/errors/6fc42c2b65664e86. Report an issue: GitHub.