mikefarah/yq · error
cannot get keys of , keys only works for maps and arrays
Error message
cannot get keys of %v, keys only works for maps and arrays
What it means
The `keys` (and `keys_unsorted`) operator returns the keys of a map or the indices of an array. For any other node kind (scalar or null), there is no meaningful key set, so the operator fails with this error, including the offending tag in the message. It exists to catch expressions applied to the wrong node type.
Solutions
- Verify the node kind first and branch: `select(kind == "map") | keys`
- Provide defaults for missing data: `.cfg // {} | keys`
- Select the actual map: `.settings | keys` instead of running keys on the root
- Convert scalars to maps upstream if keys of a wrapper object were intended
Example fix
// before
"hello" | keys
// error: cannot get keys of !!str, keys only works for maps and arrays
// after
{a: 1, b: 2} | keys # => ["a", "b"] Defensive patterns
Strategy: type-guard
Validate before calling
yq 'select(kind == "map" or kind == "seq")' input.yaml
Type guard
def keys_of(v):
return list(v.keys()) if isinstance(v, dict) else list(range(len(v))) if isinstance(v, list) else None Try / catch
out=$(yq '.cfg // {} | keys' f.yaml 2>&1) || {
echo "keys applied to non-map/non-array: $out" >&2
} Prevention
- Default optional sections: .section // {} | keys
- Branch on kind before calling keys
- Validate document shape of external inputs
- Check that the field you select is actually a map/array
When it happens
Trigger: Running `keys` on a scalar (`"hello" | keys`), on null (empty document or missing field), or on a selected field that turned out not to be a map/array.
Common situations: Assuming a YAML field is a map when it's a scalar; empty files producing null documents; optional config sections absent in some files; applying keys at the document root of a scalar-valued JSON.
Related errors
- cannot join with , can only join arrays of scalars
- cannot multiply with
- cannot pick indices from type
- cannot pivot node of type
- cannot split , can only split strings
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/9dbe01131791ea3b.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/yqlib/operator_keys.go:54
}
func keysOperator(_ *dataTreeNavigator, context Context, _ *ExpressionNode) (Context, error) {
log.Debugf("keysOperator")
var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
var targetNode *CandidateNode
switch candidate.Kind {
case MappingNode:
targetNode = getMapKeys(candidate)
case SequenceNode:
targetNode = getIndices(candidate)
default:
return Context{}, fmt.Errorf("cannot get keys of %v, keys only works for maps and arrays", candidate.Tag)
}
results.PushBack(targetNode)
}
return context.ChildContext(results), nil
}
func getMapKeys(node *CandidateNode) *CandidateNode {
contents := make([]*CandidateNode, 0)
for index := 0; index < len(node.Content); index = index + 2 {
contents = append(contents, node.Content[index])
}
seq := &CandidateNode{Kind: SequenceNode, Tag: "!!seq"}
seq.AddChildren(contents)
return seq
}View on GitHub (pinned to 8b5af0694b)