mikefarah/yq · error

%v cannot be added to %v

Error message

%v cannot be added to %v

What it means

Fallback error in subtractScalars for any tag combination that is not int-int, int-float, float-int, float-float, or datetime: yq cannot subtract these operands. Notably the message wording says 'cannot be added' — a known copy-paste artifact from the add operator — but it is raised by the subtract operator.

Source

Thrown at pkg/yqlib/operator_subtract.go:127

		target.Value = fmt.Sprintf(format, result)
	} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
		lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
		if err != nil {
			return err
		}
		rhsNum, err := strconv.ParseFloat(rhs.Value, 64)
		if err != nil {
			return err
		}
		result := lhsNum - rhsNum
		if lhsIsCustom {
			target.Tag = lhs.Tag
		} else {
			target.Tag = "!!float"
		}
		target.Value = fmt.Sprintf("%v", result)
	} else {
		return fmt.Errorf("%v cannot be added to %v", lhs.Tag, rhs.Tag)
	}

	return nil
}

func subtractDateTime(layout string, target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) error {
	var durationStr string
	if strings.HasPrefix(rhs.Value, "-") {
		durationStr = rhs.Value[1:]
	} else {
		durationStr = "-" + rhs.Value
	}
	duration, err := time.ParseDuration(durationStr)

	if err != nil {
		return fmt.Errorf("unable to parse duration [%v]: %w", rhs.Value, err)
	}

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Check both operand tags with `yq '.a | tag'` and `.b | tag'`, and fix the mismatched one
  2. Provide a numeric default for missing/null values: `.count - (.missing // 0)`
  3. Convert with `to_number` where possible; booleans need explicit conversion logic before arithmetic
  4. If the value is a datetime string, configure the correct datetime layout so it takes the subtractDateTime path

Example fix

// before: yq '.count - .missing' file.yml  -> error (.missing is null)
// after
yq '.count - (.missing // 0)' file.yml
Defensive patterns

Strategy: validation

Validate before calling

// validate operand tags are numeric before subtracting
for f in .count .other; do
  t=$(yq "$f | tag" file.yml)
  case "$t" in '!!int'|'!!float') ;; *) echo "$f is $t, not numeric"; exit 1;; esac
done

Type guard

func isNumericTag(tag string) bool {
    return tag == "!!int" || tag == "!!float"
}

Try / catch

null

Prevention

When it happens

Trigger: Subtracting booleans (`true - false`), null rhs (`5 - null` after a missing key resolves oddly), maps/other custom tags that don't guess to numeric types, e.g. `yq '.enabled - .other'` on boolean fields, or `.a - .b` where .b is !!null and lhs isn't handled by the null shortcut.

Common situations: Boolean flags mistakenly used in arithmetic; missing keys producing null operands in expressions like `.count - .missing`; datetime handling when lhs tag isn't !!timestamp and no custom layout is configured; custom tags that guess to unexpected types.

Related errors


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