grpc/grpc-go · error
nil receiver passed to UnmarshalJSON
Error message
nil receiver passed to UnmarshalJSON
What it means
codes.Code implements json.Unmarshaler (codes.go:225). If UnmarshalJSON is invoked on a nil *Code receiver — i.e. json.Unmarshal into a nil *Code — it returns this error instead of panicking on the subsequent *c = ... assignment. JSON null is handled separately as a no-op.
Source
Thrown at codes/codes.go:233
`"ABORTED"`: Aborted,
`"OUT_OF_RANGE"`: OutOfRange,
`"UNIMPLEMENTED"`: Unimplemented,
`"INTERNAL"`: Internal,
`"UNAVAILABLE"`: Unavailable,
`"DATA_LOSS"`: DataLoss,
`"UNAUTHENTICATED"`: Unauthenticated,
}
// UnmarshalJSON unmarshals b into the Code.
func (c *Code) UnmarshalJSON(b []byte) error {
// From json.Unmarshaler: By convention, to approximate the behavior of
// Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte("null")) as
// a no-op.
if string(b) == "null" {
return nil
}
if c == nil {
return fmt.Errorf("nil receiver passed to UnmarshalJSON")
}
if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {
if ci >= _maxCode {
return fmt.Errorf("invalid code: %d", ci)
}
*c = Code(ci)
return nil
}
if jc, ok := strToCode[string(b)]; ok {
*c = jc
return nil
}
return fmt.Errorf("invalid code: %q", string(b))
}
View on GitHub (pinned to 03255a9237)
Solutions
- Allocate the receiver before unmarshalling: c := new(codes.Code); json.Unmarshal(data, c).
- Unmarshal into a non-pointer codes.Code value or a wrapper struct with an allocated field.
- Use json.NewDecoder and ensure the target is addressable and non-nil.
Example fix
// before var c *codes.Code json.Unmarshal([]byte(`3`), c) // nil receiver // after c := new(codes.Code) json.Unmarshal([]byte(`3`), c)
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the *codes.Code is non-nil before unmarshalling.
func decodeCode(data []byte, c *codes.Code) error {
if c == nil { return errors.New("nil *codes.Code receiver") }
return json.Unmarshal(data, c)
} Type guard
func isCodePtr(c *codes.Code) bool { return c != nil } Prevention
- Always allocate the target before json.Unmarshal into a pointer.
- Prefer non-pointer codes.Code fields in structs you decode into.
- In reflect-based decoders, check nil before invoking UnmarshalJSON.
When it happens
Trigger: Unmarshalling JSON into a nil pointer of type *codes.Code, e.g. var c *codes.Code; json.Unmarshal(data, c), or a struct field of type *codes.Code left nil while decoding a non-null value.
Common situations: Decoding a status object or status proto JSON where the code field is a *codes.Code that was never allocated; reflect-based decoders that pass a nil pointer.
Related errors
- invalid code: %d
- invalid code: %q
- randomsubsetting: json.Unmarshal failed for configuration: %
- rls: json unmarshal failed for service config %+v: %v
- rls: json unmarshal failed for child policy config %q: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/2e01c0b6f43f6375.
Report an issue: GitHub.