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
- Check both operand tags with `yq '.a | tag'` and `.b | tag'`, and fix the mismatched one
- Provide a numeric default for missing/null values: `.count - (.missing // 0)`
- Convert with `to_number` where possible; booleans need explicit conversion logic before arithmetic
- 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
- Default null/missing operands: `.count - (.other // 0)`
- Never use boolean fields in arithmetic expressions
- Check `tag` output for custom-typed nodes to confirm they guess as numeric
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
- %v (%v) cannot be subtracted from %v
- strings cannot be subtracted
- %v (%v) cannot be subtracted from %v
- %v cannot check contained in %v
- from entries only runs against arrays
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/d0853c7304dd273a.
Report an issue: GitHub.