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

  1. Normalise the input before decoding: ensure numbers are plain JSON numbers and scalars are standard JSON types.
  2. 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).
  3. 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.
  4. 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

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


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