{"record":{"id":"fe7b5a1a54953a20","repo":"mikefarah/yq","slug":"only-arrays-are-supported-for-group-by","errorCode":null,"errorMessage":"only arrays are supported for group by","messagePattern":"only arrays are supported for group by","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/yqlib/operator_group_by.go","lineNumber":47,"sourceCode":"\t\tif !exists {\n\t\t\tgroupList = list.New()\n\t\t\tnewMatches.Set(keyValue, groupList)\n\t\t}\n\t\tgroupList.(*list.List).PushBack(child)\n\t}\n\treturn newMatches, nil\n}\n\nfunc groupBy(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {\n\n\tlog.Debugf(\"groupBy Operator\")\n\tvar results = list.New()\n\n\tfor el := context.MatchingNodes.Front(); el != nil; el = el.Next() {\n\t\tcandidate := el.Value.(*CandidateNode)\n\n\t\tif candidate.Kind != SequenceNode {\n\t\t\treturn Context{}, fmt.Errorf(\"only arrays are supported for group by\")\n\t\t}\n\n\t\tnewMatches, err := processIntoGroups(d, context, expressionNode.RHS, candidate)\n\n\t\tif err != nil {\n\t\t\treturn Context{}, err\n\t\t}\n\n\t\tresultNode := candidate.CreateReplacement(SequenceNode, \"!!seq\", \"\")\n\t\tfor groupEl := newMatches.Front(); groupEl != nil; groupEl = groupEl.Next() {\n\t\t\tgroupResultNode := &CandidateNode{Kind: SequenceNode, Tag: \"!!seq\"}\n\t\t\tgroupList := groupEl.Value.(*list.List)\n\t\t\tfor groupItem := groupList.Front(); groupItem != nil; groupItem = groupItem.Next() {\n\t\t\t\tgroupResultNode.AddChild(groupItem.Value.(*CandidateNode))\n\t\t\t}\n\n\t\t\tresultNode.AddChild(groupResultNode)\n\t\t}","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/mikefarah/yq/blob/8b5af0694bb82b41d4ae180fac9972029066f90a/pkg/yqlib/operator_group_by.go#L29-L65","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Convert object values to an array first: `. | to_entries | group_by(.value.x)` or `[.[]] | group_by(.key)`","Point the expression at the array field: `.records | group_by(.type)`","Default nulls to arrays: `.items // [] | group_by(.k)`","Fix upstream filters so they emit arrays (wrap in [...])"],"exampleFix":"// before\n{\"a\": {t: 1}, \"b\": {t: 2}} | group_by(.t)\n// error: only arrays are supported for group by\n\n// after\n{\"a\": {t: 1}, \"b\": {t: 2}} | [.[]] | group_by(.t)","handlingStrategy":"validation","validationCode":"yq '.items // [] | length' input.yaml   # confirm it's an array first","typeGuard":"def require_list(v):\n    if not isinstance(v, list):\n        raise TypeError(\"group_by input must be a list\")\n    return v","tryCatchPattern":"out=$(yq '.items // [] | group_by(.type)' f.yaml 2>&1) || {\n  echo \"group_by needs an array: $out\" >&2\n  exit 1\n}","preventionTips":["Convert object values to arrays with [.[]] before grouping","Default missing collections with // []","Verify upstream filters emit arrays, not single objects"],"tags":["yq","group-by","type-mismatch"],"backgroundTag":"operator-requires-array-input","analyzedSha":"8b5af0694bb82b41d4ae180fac9972029066f90a","analyzedAt":"2026-09-05T10:57:22.766Z","contentChangedAt":"2026-09-05T10:57:22.766Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}