kubernetes/kops · error
unhandled type at path %q: %T
Error message
unhandled type at path %q: %T
What it means
Transformer.visitAny only knows how to walk map[string]any, []any, string, int64, float64, bool, and nil. A value of any other Go type inside the tree (int, json.Number, custom structs, time.Time, etc.) cannot be transformed and produces this error naming the offending type and its JSON path. Trees are normally produced by decoding into map[string]any with encoding/json, which cannot produce such types, so this indicates values were inserted programmatically or decoded differently (e.g. yaml.v3 yields map[string]any but can yield int for small numbers).
Source
Thrown at pkg/jsonutils/transform.go:76
// visitAny is a helper function that visits any value in the JSON tree
func (o *Transformer) visitAny(v any, path string) (any, error) {
if v == nil {
return v, nil
}
switch v := v.(type) {
case map[string]any:
if err := o.visitMap(v, path); err != nil {
return nil, err
}
return v, nil
case []any:
return o.visitSlice(v, path)
case int64, float64, bool:
return o.visitPrimitive(v, path)
case string:
return o.visitString(v, path)
default:
return nil, fmt.Errorf("unhandled type at path %q: %T", path, v)
}
}
func (o *Transformer) visitMap(m map[string]any, path string) error {
for _, fn := range o.objectTransforms {
if err := fn(path, m); err != nil {
return err
}
}
for k, v := range m {
childPath := path + "." + k
v2, err := o.visitAny(v, childPath)
if err != nil {
return err
}
m[k] = v2View on GitHub (pinned to 4c8573c808)
Solutions
- Normalize the tree before Transform: convert all numbers to int64/float64 (e.g. re-marshal with encoding/json into map[string]any).
- If the tree came from YAML, convert int values to int64 in a pre-pass.
- Extend the switch in visitAny to handle the extra type if you control the library.
Example fix
// before var m map[string]any yaml.Unmarshal(data, &m) t.Transform(m) // int values fail // after j, _ := json.Marshal(m) var m2 map[string]any json.Unmarshal(j, &m2) // numbers become float64 t.Transform(m2)
Defensive patterns
Strategy: validation
Validate before calling
func normalizeJSONTypes(v any) (any, error) {
j, err := json.Marshal(v)
if err != nil {
return nil, err
}
var out any
if err := json.Unmarshal(j, &out); err != nil {
return nil, err
}
return out, nil
}
// round-trip the tree through JSON before Transformer.Transform Type guard
func isTransformable(v any) bool {
switch v.(type) {
case nil, map[string]any, []any, string, int64, float64, bool:
return true
}
return false
} Try / catch
if err := transformer.Transform(tree); err != nil {
return fmt.Errorf("transform failed: %w", err)
} Prevention
- Round-trip YAML-derived data through encoding/json before Transform.
- Avoid inserting typed Go values (structs, time.Time, json.Number) into the tree.
- Recursively check trees with isTransformable in tests.
When it happens
Trigger: Calling Transformer.Transform on a tree built from yaml.v3 Unmarshal (small integers become int, not int64), on a tree containing json.Number values, or after inserting typed values (structs, time.Time) into the map.
Common situations: Transforming YAML-derived config (kOps manifests loaded via YAML) where integer values decode as int; mixing json.Decoder(UseNumber) output with the Transformer.
Related errors
- unhandled token type %T
- error parsing version spec %q
- error encoding version spec: %v
- error building annotation patch: %v
- building node patch: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/d872b06a94041712.
Report an issue: GitHub.