mikefarah/yq · error
unrecognised type :( %v
Error message
unrecognised type :( %v
What it means
setScalarFromJson converts a decoded JSON scalar (interface{}) into a CandidateNode scalar and only understands nil, float, int, bool and string. If the JSON unmarshalling layer produces any other Go type (unexpected map/slice reaching the scalar path, or a new numeric type from a JSON library change), it returns 'unrecognised type :( %v'. This indicates the decoder met a value type it has no mapping for.
Source
Thrown at pkg/yqlib/candidate_node_json.go:42
o.Value = fmt.Sprintf("%v", value)
o.Tag = "!!float"
// json decoder returns ints as float.
if value == float64(int64(rawData.(float64))) {
// aha it's an int disguised as a float
o.Tag = "!!int"
o.Value = fmt.Sprintf("%v", int64(value.(float64)))
}
case int, int64, int32:
o.Value = fmt.Sprintf("%v", value)
o.Tag = "!!int"
case bool:
o.Value = fmt.Sprintf("%v", value)
o.Tag = "!!bool"
case string:
o.Value = rawData
o.Tag = "!!str"
default:
return fmt.Errorf("unrecognised type :( %v", rawData)
}
return nil
}
func (o *CandidateNode) UnmarshalJSON(data []byte) error {
log.Debug("UnmarshalJSON")
switch data[0] {
case '{':
log.Debug("UnmarshalJSON - its a map!")
// its a map
o.Kind = MappingNode
o.Tag = "!!map"
dec := json.NewDecoder(bytes.NewReader(data))
_, err := dec.Token() // open object
if err != nil {
return err
}View on GitHub (pinned to 8b5af0694b)
Solutions
- Normalise the input before decoding: ensure numbers are plain JSON numbers and scalars are standard JSON types.
- If using a custom decoder, configure it to return float64/int64 rather than json.Number (or add a json.Number case to setScalarFromJson and rebuild).
- Update (or pin) the yq/goccy-go-json versions to a known-good pairing; check for an existing upstream fix for the type in question.
- As a workaround, pre-convert the data with `yq -p json -o json` to canonicalise it before the failing code path.
Example fix
// before (custom decode producing json.Number) var n json.Number = "123" // hits default: unrecognised type :( 123 // after: use standard float decoding var n float64 = 123 // tagged !!int by setScalarFromJson
Defensive patterns
Strategy: validation
Validate before calling
// Ensure JSON scalars are standard before unmarshalling into CandidateNode
for _, v := range rawValues {
switch v.(type) {
case nil, bool, string, float64, float32, int, int64, int32:
// ok
default:
return fmt.Errorf("unsupported scalar %T", v)
}
} Type guard
func isSupportedJSONScalar(v interface{}) bool {
switch v.(type) {
case nil, bool, string, float64, float32, int, int64, int32:
return true
}
return false
} Try / catch
// Go
if err := node.UnmarshalJSON(data); err != nil {
if strings.Contains(err.Error(), "unrecognised type :(") {
// fall back to canonicalising the JSON first
return decodeViaCanonicalJSON(data)
}
return err
} Prevention
- Avoid custom JSON decoders that emit json.Number for scalars
- Keep goccy/go-json and yq versions pinned together
- Round-trip exotic data through `yq -p json -o json` before decoding
When it happens
Trigger: Unmarshalling JSON into CandidateNode (UnmarshalJSON → setScalarFromJson) where a scalar token decodes to an unsupported Go type — e.g. very large numbers decoded as json.Number, or library changes where nested arrays/maps are passed into the scalar path instead of being handled earlier.
Common situations: Using a custom or patched JSON decoder (goccy/go-json version changes) that yields json.Number instead of float64; feeding JSON whose structure hits an untested decoder edge (e.g. non-standard numeric formats); embedding yq's CandidateNode UnmarshalJSON in Go code with data produced by another serializer.
Related errors
- orderedMap: invalid yaml node
- no support for input format
- aborted
- unknown operator %v
- csv object encoding only works for arrays of flat objects (s
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/9da3693618cde690.
Report an issue: GitHub.