ory/hydra · error
unable to decode JSON payload into %T: %w
Error message
unable to decode JSON payload into %T: %w
What it means
After JSONScan obtains the raw text (from null, string, or []byte) it calls json.Unmarshal into the destination. This error wraps that failure, meaning the raw value is present but is not valid JSON or does not match the destination's shape (unknown fields are ignored by default, so shape/type mismatch is the usual cause).
Source
Thrown at oryx/sqlxx/types.go:504
}
// JSONScan is a generic helper for retrieving a SQL JSON-encoded value.
func JSONScan(dst, value any) error {
// Note: raw is a string (not []byte) because the MySQL driver reuses byte slices across scans.
// Using strings avoids the need to manually copy the byte slice.
var raw string
switch v := value.(type) {
case nil:
raw = "null"
case string:
raw = v
case []byte:
raw = string(v)
default:
return fmt.Errorf("unable to scan type %T as JSON into %T", value, dst)
}
if err := json.Unmarshal([]byte(raw), dst); err != nil {
return fmt.Errorf("unable to decode JSON payload into %T: %w", dst, err)
}
return nil
}
// NullInt64 represents an int64 that may be null.
// swagger:type int64
// swagger:model nullInt64
type NullInt64 struct {
Int int64
Valid bool // Valid is true if Duration is not NULL
}
// Scan implements the Scanner interface.
func (ns *NullInt64) Scan(value interface{}) error {
d := sql.NullInt64{}
if err := d.Scan(value); err != nil {
return err
}View on GitHub (pinned to 4174065ffb)
Solutions
- Print/inspect the offending raw value for the failing row and fix or migrate the stored data
- Validate the payload matches the destination shape (json.Valid, or unmarshal into json.RawMessage/map first)
- Use json.RawMessage or a flexible destination type if the column may hold heterogeneous JSON
- Pre-validate data on write with json.Marshal/strict unmarshal so bad data never reaches the DB
Example fix
// before
type Config struct { Host string `json:"host"` }
var c Config
// column value: `["a","b"]` -> unmarshal error
// after
type Config struct { Hosts []string `json:"hosts"` }
var c Config
if err := json.Unmarshal([]byte(raw), &c); err != nil {
return fmt.Errorf("unable to decode JSON payload into %T: %w", dst, err)
} Defensive patterns
Strategy: validation
Validate before calling
if !json.Valid([]byte(raw)) {
return fmt.Errorf("invalid JSON payload: %s", raw)
} Try / catch
var target MyType
if err := json.Unmarshal(data, &target); err != nil {
var syn *json.SyntaxTypeError
if errors.As(err, &syn) {
log.Printf("bad JSON syntax at offset %d", syn.Offset)
}
return fmt.Errorf("unable to decode JSON payload into %T: %w", &target, err)
} Prevention
- Validate data with json.Valid before storing in DB columns
- Use json.RawMessage destinations for heterogeneous columns
- Write via json.Marshal so stored values are always valid JSON
When it happens
Trigger: json.Unmarshal fails because the column content is malformed JSON (truncated, plain text, HTML error page stored in the column) or the JSON structure does not fit the destination type (e.g. object scanned into a slice or primitive).
Common situations: Legacy rows written before a schema/type change, application code writing non-JSON strings into a JSON column, JSON arrays stored where a struct is expected, or BOM/whitespace-corrupted payloads.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to scan type %T as JSON into %T
- cannot scan %#v into StringSliceJSONFormat
- expected JSON value to be an array but got type: %s
- The DSN connection string looks like a SQLite connection, bu
- unsupported DSN type
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/f9814ef34b97c2dd.
Report an issue: GitHub.