jmoiron/sqlx · error
Incompatible type for JSONText
Error message
Incompatible type for JSONText
What it means
JSONText.Scan implements sql.Scanner and accepts string, []byte, and nil (SQL NULL maps to empty JSON). Any other driver type cannot be treated as JSON text, so Scan returns this error. The message is capitalized intentionally to preserve backwards compatibility.
Source
Thrown at types/types.go:106
}
// Scan stores the src in *j. No validation is done.
func (j *JSONText) Scan(src interface{}) error {
var source []byte
switch t := src.(type) {
case string:
source = []byte(t)
case []byte:
if len(t) == 0 {
source = emptyJSON
} else {
source = t
}
case nil:
*j = emptyJSON
default:
//lint:ignore ST1005 changing this could break consumers of this package
return errors.New("Incompatible type for JSONText")
}
*j = append((*j)[0:0], source...)
return nil
}
// Unmarshal unmarshal's the json in j to v, as in json.Unmarshal.
func (j *JSONText) Unmarshal(v interface{}) error {
if len(*j) == 0 {
*j = emptyJSON
}
return json.Unmarshal([]byte(*j), v)
}
// String supports pretty printing for JSONText types.
func (j JSONText) String() string {
return string(j)
}
View on GitHub (pinned to 41dac167fd)
Solutions
- Verify the column actually stores JSON as text and the driver returns []byte/string.
- Scan into []byte first and assign via j.Scan(raw) or append manually.
- Use the correct sqlx type for the column's real type (Int64Text-like handling or plain types).
- Upgrade/downgrade the driver or configure it to return strings for text columns.
Example fix
// before var j types.JSONText row.Scan(&j) // src is time.Time // after var raw []byte row.Scan(&raw) j.Scan(raw)
Defensive patterns
Strategy: type-guard
Validate before calling
func jsonTextScannable(src interface{}) bool {
switch src.(type) {
case []byte, string, nil:
return true
default:
return false
}
} Type guard
func assertJSONSource(v interface{}) ([]byte, bool) {
switch t := v.(type) {
case []byte:
return t, true
case string:
return []byte(t), true
}
return nil, false
} Try / catch
var j types.JSONText
if err := row.Scan(&j); err != nil {
if err.Error() == "Incompatible type for JSONText" {
// log reflect.TypeOf(src) from a plain interface{} scan
}
return err
} Prevention
- Use JSONText only on text/blob columns the driver returns as string/[]byte.
- Check column DDL and driver type mapping during setup.
- Treat NULL as valid (Scan maps nil to empty JSON) but non-text types as a bug.
- Pre-scan into []byte when the driver's return type is uncertain.
When it happens
Trigger: Scanning a column whose driver value is neither string, []byte, nor nil into a JSONText field — e.g. int64/float64 from a numeric column, time.Time from a timestamp column, or bool.
Common situations: JSONText used on an integer/timestamp column by mistake; a driver returning different types for TEXT/BLOB (some return string, others []byte, some custom types); ORM/driver version changes altering returned types.
Related errors
- Incompatible type for GzippedText
- argument not a struct
- missing field
- bad []byte type assertion
- JSONText: UnmarshalJSON on nil pointer
AI-assisted analysis of jmoiron/sqlx@41dac167fd (2026-09-03).
Data as JSON: /api/errors/d915cf8537bf0519.
Report an issue: GitHub.