mikefarah/yq · critical
panic(err) on ParseFloat failure while sorting numeric value
Error message
panic(err) on ParseFloat failure while sorting numeric values
What it means
The sort compare function panics when comparing values tagged !!int/!!float (mixed) and strconv.ParseFloat fails on the left operand at operator_sort.go:176-179. This branch is reached when one side is !!float, so even a valid-looking int value gets re-parsed as float; any value string ParseFloat rejects (NaN-like words, underscores, hex, empty) triggers the panic inside sort.Less, killing the process.
Source
Thrown at pkg/yqlib/operator_sort.go:178
} else if lhsTag == "!!int" && rhsTag == "!!int" {
_, lhsNum, err := parseInt64(lhs.Value)
if err != nil {
panic(err)
}
_, rhsNum, err := parseInt64(rhs.Value)
if err != nil {
panic(err)
}
if lhsNum < rhsNum {
return -1
} else if lhsNum > rhsNum {
return 1
}
return 0
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
if err != nil {
panic(err)
}
rhsNum, err := strconv.ParseFloat(rhs.Value, 64)
if err != nil {
panic(err)
}
if lhsNum == rhsNum {
return 0
} else if lhsNum < rhsNum {
return -1
}
return 1
}
return strings.Compare(lhs.Value, rhs.Value)
}
View on GitHub (pinned to 8b5af0694b)
Solutions
- Scan the array before sorting and fix values whose tags are numeric but whose text is not ParseFloat-compatible: `yq '.[] | select(tag == "!!float" or tag == "!!int")'.
- Normalize YAML 1.1 hex/underscore literals to decimal, or retag them !!str for lexicographic sort: `sort_by(.v | tag="!!str")`.
- Replace empty/placeholder numerics with real numbers or strings before sorting.
- Force the whole field to !!str when numeric fidelity is not required, avoiding both numeric branches entirely.
- Upgrade yq so ParseFloat failures degrade to string comparison instead of panicking.
Example fix
# before
yq 'sort_by(.score)' m.yaml # .score: [1.5, 0x1F] -> ParseFloat("0x1F") panics
# after
yq '(.score[] | select(tag == "!!int" and (. =~ "^0x"))) |= (tag="!!str")' m.yaml | yq 'sort_by(.score)' Defensive patterns
Strategy: validation
Validate before calling
# find numeric-tagged values Go ParseFloat would reject
yq '.[] | select(tag == "!!int" or tag == "!!float") | select(test("^[-+]?([0-9]*\\.)?[0-9]+([eE][-+]?[0-9]+)?$") | not)' m.yaml Type guard
// Go: float parseability guard
func isParseableFloat(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
} Try / catch
out, err := func() (out string, err error) {
defer func() { if r := recover(); r != nil { err = fmt.Errorf("sort ParseFloat panic: %v", r) } }()
out = runYq("sort_by(.score)")
return
}() Prevention
- Sanitize mixed int/float arrays before sorting; drop or retag placeholders like empty strings
- Convert YAML 1.1 literals (0x10, 1_000) to decimal or !!str upstream
- Keep locale-formatted numbers out of numerically tagged fields
- Validate numeric columns from CSV/JSON imports before running sort_by
When it happens
Trigger: sort/sort_by on an array containing at least one !!float element alongside a node whose .Value cannot be parsed as a float64 despite its numeric tag: e.g. `"1.2.3"` tagged !!float, `""` tagged !!int, `0x1F` tagged !!int, or `Inf`/`NaN` spellings unsupported by ParseFloat.
Common situations: Mixing integers and floats in one array where one value is malformed; data converted from formats that allow hex/octal numeric literals (YAML 1.1 `0x1F`, `1_000`) which Go's ParseFloat rejects; empty-string placeholders tagged numeric by a pipeline; scientific-notation edge cases.
Related errors
- panic(err) on parseInt64 failure while sorting !!int values
- panic(err) on copier.Copy failure of traverse preferences
- no support for input format
- aborted
- unrecognised type :( %v
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/9393daaaa07fc2fd.
Report an issue: GitHub.