Repository navigation
A --jq expression that inspects a type panics: jqUnwrapNumbers hands gojq an int64 #749
Description
Feature: #833 — Renderings: the pipeline from result value to stdout
A --jq expression that inspects a value's type crashes the process.
Reproduction
$ devlore-test run --jq '[paths(scalars) as $p | "\($p|map(tostring)|join(".")): \(getpath($p))"]' \
-o value test_hello.star
panic: invalid type: int64 (1)
goroutine 1 [running]:
github.com/itchyny/gojq.TypeOf(...) type.go:29
github.com/itchyny/gojq.funcType(...) func.go:517
Any expression reaching TypeOf over an integer does it: tostring, type, tonumber, and the arithmetic
paths, among others.
Cause
gojq's accepted types are exactly nil, bool, int, float64, *big.Int, json.Number, string,
[]any, map[string]any -- type.go:20-30, whose default branch is the panic above.
jqUnwrapNumbers (pkg/result/jq_filter.go:121) hands it something else:
case json.Number:
if i, err := v.Int64(); err == nil {
return i // int64, which is NOT in gojq's table
}v.Int64() returns int64. Every integer that survives a --jq expression is therefore a value gojq will
panic on the moment anything asks its type.
The conversion is not needed
gojq handles json.Number natively and everywhere -- comparison (compare.go:67), encoding
(encoder.go:66), and a dozen sites across func.go including tostring, tonumber, and the arithmetic
operators. option.go:36 states the contract: "On handling numbers, take account of int, float64, *big.Int,
and json.Number."
The function's own comment claims it "keeps == comparisons stable across integer and float". That does not
hold: compare.go:67 puts json.Number in the same case as int and float64, so gojq already compares
them uniformly.
It is also lossy
Int64() fails for a number beyond int64, and the fallback is Float64(), which rounds. An integer past
2^53 loses digits inside the filter -- the same defect #712 records against the document codec, and the
reason normalize deliberately keeps json.Number for the presenters.
Fix
Delete jqUnwrapNumbers and pass the normalized value to gojq unchanged. That removes the panic, removes the
rounding, and removes a conversion gojq never wanted.
Verification
- The reproduction above completes and prints flattened paths.
--jq '.unit_count | tostring'returns the number as a string rather than panicking.- An integer past 2^53 survives a
--jqexpression with its digits intact.
Activity
fix(result): a table row survives its own newlines, and jq survives i…
Every presentation is a presentation of the JSON: formatting rules, l…