mikefarah/yq · error

only arrays are supported for group by

Error message

only arrays are supported for group by

What it means

`group_by(expr)` collects array elements into sub-arrays keyed by the expression result. It only operates on SequenceNode inputs; applying it to a map, scalar, or null yields this error. The check happens per candidate before groups are computed.

Source

Thrown at pkg/yqlib/operator_group_by.go:47

		if !exists {
			groupList = list.New()
			newMatches.Set(keyValue, groupList)
		}
		groupList.(*list.List).PushBack(child)
	}
	return newMatches, nil
}

func groupBy(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {

	log.Debugf("groupBy Operator")
	var results = list.New()

	for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
		candidate := el.Value.(*CandidateNode)

		if candidate.Kind != SequenceNode {
			return Context{}, fmt.Errorf("only arrays are supported for group by")
		}

		newMatches, err := processIntoGroups(d, context, expressionNode.RHS, candidate)

		if err != nil {
			return Context{}, err
		}

		resultNode := candidate.CreateReplacement(SequenceNode, "!!seq", "")
		for groupEl := newMatches.Front(); groupEl != nil; groupEl = groupEl.Next() {
			groupResultNode := &CandidateNode{Kind: SequenceNode, Tag: "!!seq"}
			groupList := groupEl.Value.(*list.List)
			for groupItem := groupList.Front(); groupItem != nil; groupItem = groupItem.Next() {
				groupResultNode.AddChild(groupItem.Value.(*CandidateNode))
			}

			resultNode.AddChild(groupResultNode)
		}

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Convert object values to an array first: `. | to_entries | group_by(.value.x)` or `[.[]] | group_by(.key)`
  2. Point the expression at the array field: `.records | group_by(.type)`
  3. Default nulls to arrays: `.items // [] | group_by(.k)`
  4. Fix upstream filters so they emit arrays (wrap in [...])

Example fix

// before
{"a": {t: 1}, "b": {t: 2}} | group_by(.t)
// error: only arrays are supported for group by

// after
{"a": {t: 1}, "b": {t: 2}} | [.[]] | group_by(.t)
Defensive patterns

Strategy: validation

Validate before calling

yq '.items // [] | length' input.yaml   # confirm it's an array first

Type guard

def require_list(v):
    if not isinstance(v, list):
        raise TypeError("group_by input must be a list")
    return v

Try / catch

out=$(yq '.items // [] | group_by(.type)' f.yaml 2>&1) || {
  echo "group_by needs an array: $out" >&2
  exit 1
}

Prevention

When it happens

Trigger: Running `group_by(.key)` on a top-level object instead of an array; piping a single scalar into group_by; a preceding filter that returns one object rather than a list.

Common situations: JSON input whose root is a map of records; expecting group_by to also work over map values; selecting `.items` where the key is missing (null) then grouping.

Related errors


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