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.Tag

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Wrap the right operand in an array so both sides are sequences: `.myList - [.removedItem]`
  2. Check the kind of both operands with `type` first (e.g. `select(type == "!!seq")`) and fix the data or the expression
  3. If you meant element-wise numeric subtraction, use map over elements instead: `.myList | map(. - 2)`
  4. 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

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


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