mikefarah/yq · error
%v not yet supported for contains
Error message
%v not yet supported for contains
What it means
The yq `contains` operator only supports comparing mapping, sequence, and scalar nodes. When the left-hand node's kind is none of those (e.g. an alias/anchor node kind, or an unrecognised node kind), `contains()` falls through its switch and returns this error. It is a hard 'not implemented' guard, not a data mismatch.
Source
Thrown at pkg/yqlib/operator_contains.go:92
}
func contains(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
switch lhs.Kind {
case MappingNode:
return containsObject(lhs, rhs)
case SequenceNode:
return containsArray(lhs, rhs)
case ScalarNode:
if rhs.Kind != ScalarNode || lhs.Tag != rhs.Tag {
return false, nil
}
if lhs.Tag == "!!null" {
return rhs.Tag == "!!null", nil
}
return containsScalars(lhs, rhs)
}
return false, fmt.Errorf("%v not yet supported for contains", lhs.Tag)
}
func containsWithNodes(_ *dataTreeNavigator, _ Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
if lhs.Kind != rhs.Kind {
return nil, fmt.Errorf("%v cannot check contained in %v", rhs.Tag, lhs.Tag)
}
result, err := contains(lhs, rhs)
if err != nil {
return nil, err
}
return createBooleanCandidate(lhs, result), nil
}
View on GitHub (pinned to 8b5af0694b)
Solutions
- Inspect the input node kind with `yq --debug-node-info` or print the tag (`.tag`) to see what unsupported kind the LHS holds
- Dereference aliases before comparing (e.g. use `(.foo // empty)` or re-parse the input) so nodes are concrete map/seq/scalar values
- Convert the value to a supported form first, e.g. force a scalar with `= .value` or select the concrete node instead of the anchor
- If it happens on legitimately supported data, upgrade yq — this guard has shrunk as more kinds gained support
Example fix
// before: contains on an aliased node
yq '.a contains "x"' <<< 'a: &val {b: x}'
// after: dereference/return the concrete value first
yq '(.a | .) contains {b: "x"}' <<< 'a: &val {b: x}' Defensive patterns
Strategy: type-guard
Validate before calling
// check kind before running contains in a yq pipeline
yq 'select(type == "!!map" or type == "!!seq" or type == "!!str") | . contains (...)'
// in Go embedding yqlib: switch node.Kind {
// case yqlib.MappingNode, yqlib.SequenceNode, yqlib.ScalarNode: /* safe */
// default: skip contains
// } Type guard
func containsSupported(n *yqlib.CandidateNode) bool {
switch n.Kind {
case yqlib.MappingNode, yqlib.SequenceNode, yqlib.ScalarNode:
return true
}
return false
} Prevention
- Dereference YAML aliases before comparison so nodes are concrete map/seq/scalar
- Print node tags with .tag or --debug-node-info when debugging odd inputs
- Keep yq updated; supported kinds for contains have expanded over time
- Validate input documents with a schema before running contains-style filters
When it happens
Trigger: Running a `contains` expression where the LHS document node has a Kind other than MappingNode, SequenceNode, or ScalarNode (e.g. an unresolved alias node, kind 0/null-kind node, or a future node kind). The error bubbles up from containsArrayElement/containsObject when an element reached via recursion has such a kind.
Common situations: Feeding yq input in a format whose decoder produces exotic node kinds (e.g. tagged/aliased nodes in YAML), piping documents where a key resolves to an alias rather than a value, or using a very old/new yq version where node kinds differ. Very rare in normal use since YAML decoders mostly emit map/seq/scalar.
Related errors
- maps not yet supported for comparison
- arrays not yet supported for comparison
- %v not yet supported for comparison
- %v cannot check contained in %v
- can only pivot elements of !!seq or !!map types, received %v
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/27b8146c614b01b5.
Report an issue: GitHub.