plandex-ai/plandex · error
unsupported data type: %T
Error message
unsupported data type: %T
What it means
ModelRoleConfig implements sql.Scanner; its Scan method only accepts []byte and string (JSON text from the DB column) and rejects any other driver.Value type with this error. It fires when the database driver hands Scan a value type it does not handle, typically nil/NULL or a non-text type.
Source
Thrown at app/shared/ai_models_data_models.go:669
customModel := customModels[m.ModelId]
if customModel != nil {
return &customModel.BaseModelShared
}
return nil
}
func (m *ModelRoleConfig) Scan(src interface{}) error {
if src == nil {
return nil
}
switch s := src.(type) {
case []byte:
return json.Unmarshal(s, m)
case string:
return json.Unmarshal([]byte(s), m)
default:
return fmt.Errorf("unsupported data type: %T", src)
}
}
func (m ModelRoleConfig) Value() (driver.Value, error) {
return json.Marshal(m)
}
type PlannerRoleConfig struct {
ModelRoleConfig
PlannerModelConfig
}
func (p *PlannerRoleConfig) Scan(src interface{}) error {
if src == nil {
return nil
}
switch s := src.(type) {
case []byte:View on GitHub (pinned to e2d772072e)
Solutions
- COALESCE the column in SQL (e.g. SELECT COALESCE(model_role_config, '{}')) so NULL never reaches Scan.
- Add a nil case to the switch: if src == nil { *m = ModelRoleConfig{}; return nil }.
- Ensure the column type is JSONB/TEXT so the driver delivers []byte or string.
- Check the driver/ORM version for changed column decoding behavior.
Example fix
// before
switch s := src.(type) {
case []byte:
return json.Unmarshal(s, m)
case string:
return json.Unmarshal([]byte(s), m)
default:
return fmt.Errorf("unsupported data type: %T", src)
}
// after
switch s := src.(type) {
case nil:
*m = ModelRoleConfig{}
return nil
case []byte:
return json.Unmarshal(s, m)
case string:
return json.Unmarshal([]byte(s), m)
default:
return fmt.Errorf("unsupported data type: %T", src)
} Defensive patterns
Strategy: type-guard
Validate before calling
// ensure the column is never NULL in SQL
var cfg ModelRoleConfig
err := db.QueryRow("SELECT COALESCE(model_role_config, '{}'::jsonb) FROM orgs WHERE id=$1", orgId).Scan(&cfg) Type guard
func scanableJSON(src any) bool {
switch src.(type) {
case []byte, string:
return true
default:
return false
}
} Try / catch
var cfg ModelRoleConfig
err := rows.Scan(&cfg)
if err != nil {
var typeErr *json.UnmarshalTypeError
if strings.Contains(err.Error(), "unsupported data type") {
cfg = ModelRoleConfig{} // fall back to zero value
} else {
return err
}
} Prevention
- Add nil handling to every sql.Scanner implementation for JSON columns.
- Use COALESCE/NOT NULL DEFAULT '{}' on all JSONB config columns.
- Test Scan against NULL and empty-string values in unit tests.
- Keep column types JSONB/TEXT so drivers deliver bytes or strings.
When it happens
Trigger: Scanning a NULL model_role_config column into a ModelRoleConfig field (driver passes nil, which hits default); a driver returning []int or other unusual types for the column.
Common situations: Reading a row where the JSONB config column is NULL without COALESCE; using a driver or ORM that decodes JSON columns into types other than []byte/string; direct raw queries returning typed columns.
Related errors
- unsupported data type: %T
- unsupported data type: %T
- unsupported data type: %T
- unsupported data type: %T
- error invalidating conflicted results: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/62e3ec0257ee9f63.
Report an issue: GitHub.