jmoiron/sqlx · error
JSONText: UnmarshalJSON on nil pointer
Error message
JSONText: UnmarshalJSON on nil pointer
What it means
JSONText.UnmarshalJSON implements json.Unmarshaler and requires a non-nil receiver, since it appends data into the existing slice. Calling it on a nil *JSONText would be unsafe/meaningless, so it returns this error. This typically surfaces when json.Unmarshal calls back into a nil pointer field.
Source
Thrown at types/types.go:73
// Value() validates the json format in the source, and returns an error if
// the json is not valid. Scan does no validation. JSONText additionally
// implements `Unmarshal`, which unmarshals the json within to an interface{}
type JSONText json.RawMessage
var emptyJSON = JSONText("{}")
// MarshalJSON returns the *j as the JSON encoding of j.
func (j JSONText) MarshalJSON() ([]byte, error) {
if len(j) == 0 {
return emptyJSON, nil
}
return j, nil
}
// UnmarshalJSON sets *j to a copy of data
func (j *JSONText) UnmarshalJSON(data []byte) error {
if j == nil {
return errors.New("JSONText: UnmarshalJSON on nil pointer")
}
*j = append((*j)[0:0], data...)
return nil
}
// Value returns j as a value. This does a validating unmarshal into another
// RawMessage. If j is invalid json, it returns an error.
func (j JSONText) Value() (driver.Value, error) {
var m json.RawMessage
var err = j.Unmarshal(&m)
if err != nil {
return []byte{}, err
}
return []byte(j), nil
}
// Scan stores the src in *j. No validation is done.
func (j *JSONText) Scan(src interface{}) error {View on GitHub (pinned to 41dac167fd)
Solutions
- Initialize the JSONText before unmarshaling: use a value (JSONText) field or allocate with new(types.JSONText).
- Ensure the containing struct field is populated/allocated before json.Unmarshal runs.
- If scanning from SQL, prefer GzippedText/JSONText value semantics (var t types.JSONText).
- Wrap unmarshal and handle the error by allocating and retrying once.
Example fix
// before
var t *types.JSONText
json.Unmarshal(data, t) // nil pointer
// after
t := &types.JSONText{}
json.Unmarshal(data, t) Defensive patterns
Strategy: type-guard
Validate before calling
func safeUnmarshalJSONText(data []byte, j **types.JSONText) error {
if j == nil || *j == nil {
*j = new(types.JSONText)
}
return json.Unmarshal(data, j)
} Type guard
func nonNilJSONText(j *types.JSONText) *types.JSONText {
if j == nil {
return new(types.JSONText)
}
return j
} Try / catch
if err := json.Unmarshal(data, &t); err != nil {
if strings.Contains(err.Error(), "UnmarshalJSON on nil pointer") {
t = &types.JSONText{}
err = json.Unmarshal(data, &t)
}
return err
} Prevention
- Declare JSONText fields by value, not *JSONText.
- Always allocate pointer fields with new()/&{} before unmarshal.
- Never pass a nil *JSONText directly to json.Unmarshal.
- Handle decoder errors by re-initializing and retrying once.
When it happens
Trigger: json.Unmarshal(data, (*types.JSONText)(nil)); unmarshaling into a nil JSONText pointer field in a struct; JSON libraries calling UnmarshalJSON through a nil receiver.
Common situations: Struct field declared as *JSONText left nil by another decoder step; manual re-use of a pointer variable that was reset to nil; passing a nil pointer obtained from a failed previous decode.
Related errors
AI-assisted analysis of jmoiron/sqlx@41dac167fd (2026-09-03).
Data as JSON: /api/errors/d216e6b8730e0d64.
Report an issue: GitHub.