go-gorm/gorm · error
unsupported data type %v for %v on field %s
Error message
unsupported data type %v for %v on field %s
What it means
While guessing a relation, GORM found the field's underlying kind is neither Struct nor Slice, so it cannot build has/belongs-to/many2many semantics. Struct maps to guessGuess, Slice to guessHas; anything else (map, string, int, chan, func, array-of-non-struct after indirection) reaches the default branch and sets schema.err.
Source
Thrown at schema/relationship.go:96
if relation.FieldSchema, err = getOrParse(fieldValue, schema.cacheStore, schema.namer); err != nil {
schema.err = fmt.Errorf("failed to parse field: %s, error: %w", field.Name, err)
return nil
}
if hasPolymorphicRelation(field.TagSettings) {
schema.buildPolymorphicRelation(relation, field)
} else if many2many := field.TagSettings["MANY2MANY"]; many2many != "" {
schema.buildMany2ManyRelation(relation, field, many2many)
} else if belongsTo := field.TagSettings["BELONGSTO"]; belongsTo != "" {
schema.guessRelation(relation, field, guessBelongs)
} else {
switch field.IndirectFieldType.Kind() {
case reflect.Struct:
schema.guessRelation(relation, field, guessGuess)
case reflect.Slice:
schema.guessRelation(relation, field, guessHas)
default:
schema.err = fmt.Errorf("unsupported data type %v for %v on field %s", relation.FieldSchema, schema,
field.Name)
}
}
if relation.Type == has {
if relation.FieldSchema != relation.Schema && relation.Polymorphic == nil && field.OwnerSchema == nil {
relation.FieldSchema.Relationships.Mux.Lock()
relation.FieldSchema.Relationships.Relations["_"+relation.Schema.Name+"_"+relation.Name] = relation
relation.FieldSchema.Relationships.Mux.Unlock()
}
switch field.IndirectFieldType.Kind() {
case reflect.Struct:
relation.Type = HasOne
case reflect.Slice:
relation.Type = HasMany
}
}View on GitHub (pinned to 1d6ce99528)
Solutions
- Implement driver.Valuer and sql.Scanner on the field's type so GORM treats it as a scalar column.
- Or add a serializer: `gorm:"serializer:json"`.
- Or exclude the field with `gorm:"-"` if it should not be persisted.
- If the field should be a relation, change its type to the related struct or a slice of it.
Example fix
// before
type User struct {
ID uint
Roles map[string]bool // unsupported kind: map
}
// after
type User struct {
ID uint
Roles map[string]bool `gorm:"serializer:json"`
} Defensive patterns
Strategy: validation
Validate before calling
// Reject non-struct, non-slice relation fields before migrate
func validRelationKind(t reflect.Type) bool {
for t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice || t.Kind() == reflect.Array {
t = t.Elem()
}
return t.Kind() == reflect.Struct
} Try / catch
if err := db.AutoMigrate(&User{}); err != nil && strings.Contains(err.Error(), "unsupported data type") {
return fmt.Errorf("check model fields for maps/scalars needing serializer or gorm:\": %w", err)
} Prevention
- Tag every map/custom-composite field with serializer:json (or gob).
- Implement Valuer/Scanner for scalar custom types used as columns.
- Lint models in CI with a reflect-based struct walker that flags map/chan/func fields lacking tags.
When it happens
Trigger: A model field whose indirect type kind is not struct or slice and that reaches the relation builder — typically a custom named type based on a map or string that does not implement Valuer/Scanner, or an array like `[4]byte` used without a serializer tag.
Common situations: Custom type aliases (e.g. `type JSONB map[string]interface{}`) used on models without serializer or Valuer/Scanner; fields typed as channels or funcs; migrating a field from a struct to a scalar type without updating tags.
Related errors
- unsupported data type
- failed to parse field: %s, error: %w
- invalid polymorphic type %v for %v on field %s, missing fiel
- unsupported relationship
- failed to get schema
AI-assisted analysis of go-gorm/gorm@1d6ce99528 (2026-08-15).
Data as JSON: /api/errors/30da7082cfb132b2.
Report an issue: GitHub.