mikefarah/yq · error
%v (%v) cannot be subtracted from %v
Error message
%v (%v) cannot be subtracted from %v
What it means
yq's subtract operator (`-`) only supports sequence - sequence (array difference), scalar - scalar, and null - anything. This error is thrown when the LEFT operand is an array (SequenceNode) but the RIGHT operand is not an array (e.g. a scalar or map), because there is no defined way to 'subtract' a non-array from an array. The message reports the offending rhs tag, its nice path, and the lhs tag.
Source
Thrown at pkg/yqlib/operator_subtract.go:55
newLHSArray = append(newLHSArray, lhs.Content[lindex])
}
}
return newLHSArray
}
func subtract(_ *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
if lhs.Tag == "!!null" {
return lhs.CopyAsReplacement(rhs), nil
}
target := lhs.CopyWithoutContent()
switch lhs.Kind {
case MappingNode:
return nil, fmt.Errorf("maps not yet supported for subtraction")
case SequenceNode:
if rhs.Kind != SequenceNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhs.Tag)
}
target.Content = subtractArray(lhs, rhs)
case ScalarNode:
if rhs.Kind != ScalarNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhs.Tag)
}
target.Kind = ScalarNode
target.Style = lhs.Style
if err := subtractScalars(context, target, lhs, rhs); err != nil {
return nil, err
}
}
return target, nil
}
func subtractScalars(context Context, target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) error {
lhsTag := lhs.TagView on GitHub (pinned to 8b5af0694b)
Solutions
- Wrap the right operand in an array so both sides are sequences: `.myList - [.removedItem]`
- Check the kind of both operands with `type` first (e.g. `select(type == "!!seq")`) and fix the data or the expression
- If you meant element-wise numeric subtraction, use map over elements instead: `.myList | map(. - 2)`
- If the right value should be a list, fix the input document or select the correct key
Example fix
// before: yq '.items - 3' file.yml -> error // after yq '.items - [3]' file.yml
Defensive patterns
Strategy: validation
Validate before calling
// shell check before running the expression
lhs_type=$(yq '.lhs | type' file.yml)
rhs_type=$(yq '.rhs | type' file.yml)
[ "$lhs_type" = "!!seq" ] && [ "$rhs_type" = "!!seq" ] || { echo "subtract needs seq-seq, got $lhs_type - $rhs_type"; exit 1; } Type guard
def is_seq(node):
return node.get('kind') == 'sequence' # or use yq 'type' == '!!seq' Try / catch
null
Prevention
- Always wrap single-element removals in an array: `.list - [item]`
- Check operand kinds with `type` when expression inputs come from varying documents
- Prefer `map(. - n)` for element-wise numeric ops on arrays
When it happens
Trigger: Running a yq expression like `[1,2,3] - 2`, `.a[] - .b` where .a is a sequence and .b is a scalar/map, or `.myList - .notAList` in any yq invocation (CLI or Go API via subtractOperator).
Common situations: Config transform scripts where the user assumes `-` removes a single element from an array; a YAML key that changed from scalar to list (or vice versa) upstream so the expression now mixes kinds; copy-pasted jq-style expressions assuming scalar set membership removal.
Related errors
- cannot join with %v, can only join arrays of scalars
- strings cannot be subtracted
- %v cannot be added to %v
- %v (%v) cannot be subtracted from %v
- %v cannot check contained in %v
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/c49e39afffc5d4fc.
Report an issue: GitHub.