knadh/listmonk · error
could not not decode type %T -> %T
Error message
could not not decode type %T -> %T
What it means
StringIntMap implements sql.Scanner; Scan expects nil or []byte (JSONB from Postgres). If the driver delivers any other Go type, json.Unmarshal can't be attempted and this (typo'd) error is returned describing the source and target types.
Solutions
- Add a string case: if data, ok := b.(string); ok { return json.Unmarshal([]byte(data), &s) }
- Ensure the query doesn't cast the JSONB column to text; select it as-is so the driver returns []byte
- Pass []byte(...) when calling Scan directly in tests/code
Example fix
// before
if data, ok := b.([]byte); ok {
return json.Unmarshal(data, &s)
}
// after
switch data := b.(type) {
case []byte:
return json.Unmarshal(data, &s)
case string:
return json.Unmarshal([]byte(data), &s)
} Defensive patterns
Strategy: type-guard
Validate before calling
switch v := value.(type) {
case nil, []byte:
// OK to pass to Scan
case string:
value = []byte(v)
default:
return fmt.Errorf("cannot scan %T into StringIntMap", value)
} Type guard
func isScannableJSONB(v any) bool {
switch v.(type) {
case nil, []byte, string:
return true
}
return false
} Try / catch
if err := m.Scan(dbValue); err != nil {
if strings.Contains(err.Error(), "could not not decode") {
// coerce dbValue to []byte (if string) and retry once
}
} Prevention
- Select JSONB columns without ::text casts
- Pin a single Postgres driver so JSONB consistently arrives as []byte
- Extend Scan with a string case for defensive parsing
When it happens
Trigger: Database/driver returns a value that is neither nil nor []byte — e.g. a string instead of []byte — when scanning a JSONB column into StringIntMap.
Common situations: Using a driver or scan helper that decodes JSONB into string instead of []byte; hand-written queries casting the column (e.g. ::text); unit tests passing string values to Scan.
Related errors
- error fetching campaign subscribers
- error parsing lang file
- error reading validation data
- error unmarshalling azure event
- error unmarshalling azure notification array
AI-assisted analysis of knadh/listmonk@670c01717d (2026-09-01).
Data as JSON: /api/errors/3a61fc5db173b8d2.
Report an issue: GitHub.
Appendix: source
Thrown at models/common.go:133
// StringIntMap is used to define DB Scan()s.
type StringIntMap map[string]int
// Value returns the JSON marshalled SubscriberAttribs.
func (s JSON) Value() (driver.Value, error) {
return json.Marshal(s)
}
// Scan unmarshals JSONB from the DB.
func (s JSON) Scan(b any) error {
if b == nil {
s = make(JSON)
return nil
}
if data, ok := b.([]byte); ok {
return json.Unmarshal(data, &s)
}
return fmt.Errorf("could not not decode type %T -> %T", b, s)
}
// Scan unmarshals JSONB from the DB.
func (s StringIntMap) Scan(src any) error {
if src == nil {
s = make(StringIntMap)
return nil
}
if data, ok := src.([]byte); ok {
return json.Unmarshal(data, &s)
}
return fmt.Errorf("could not not decode type %T -> %T", src, s)
}
// Scan implements the sql.Scanner interface.
func (h *Headers) Scan(src any) error {
var b []byteView on GitHub (pinned to 670c01717d)