{"record":{"id":"30da7082cfb132b2","repo":"go-gorm/gorm","slug":"unsupported-data-type-v-for-v-on-field-s","errorCode":null,"errorMessage":"unsupported data type %v for %v on field %s","messagePattern":"unsupported data type (.+?) for (.+?) on field (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schema/relationship.go","lineNumber":96,"sourceCode":"\tif relation.FieldSchema, err = getOrParse(fieldValue, schema.cacheStore, schema.namer); err != nil {\n\t\tschema.err = fmt.Errorf(\"failed to parse field: %s, error: %w\", field.Name, err)\n\t\treturn nil\n\t}\n\n\tif hasPolymorphicRelation(field.TagSettings) {\n\t\tschema.buildPolymorphicRelation(relation, field)\n\t} else if many2many := field.TagSettings[\"MANY2MANY\"]; many2many != \"\" {\n\t\tschema.buildMany2ManyRelation(relation, field, many2many)\n\t} else if belongsTo := field.TagSettings[\"BELONGSTO\"]; belongsTo != \"\" {\n\t\tschema.guessRelation(relation, field, guessBelongs)\n\t} else {\n\t\tswitch field.IndirectFieldType.Kind() {\n\t\tcase reflect.Struct:\n\t\t\tschema.guessRelation(relation, field, guessGuess)\n\t\tcase reflect.Slice:\n\t\t\tschema.guessRelation(relation, field, guessHas)\n\t\tdefault:\n\t\t\tschema.err = fmt.Errorf(\"unsupported data type %v for %v on field %s\", relation.FieldSchema, schema,\n\t\t\t\tfield.Name)\n\t\t}\n\t}\n\n\tif relation.Type == has {\n\t\tif relation.FieldSchema != relation.Schema && relation.Polymorphic == nil && field.OwnerSchema == nil {\n\t\t\trelation.FieldSchema.Relationships.Mux.Lock()\n\t\t\trelation.FieldSchema.Relationships.Relations[\"_\"+relation.Schema.Name+\"_\"+relation.Name] = relation\n\t\t\trelation.FieldSchema.Relationships.Mux.Unlock()\n\t\t}\n\n\t\tswitch field.IndirectFieldType.Kind() {\n\t\tcase reflect.Struct:\n\t\t\trelation.Type = HasOne\n\t\tcase reflect.Slice:\n\t\t\trelation.Type = HasMany\n\t\t}\n\t}","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/go-gorm/gorm/blob/1d6ce99528060be18a42be09aca8d39efcb47f28/schema/relationship.go#L78-L114","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ntype User struct {\n    ID    uint\n    Roles map[string]bool // unsupported kind: map\n}\n\n// after\ntype User struct {\n    ID    uint\n    Roles map[string]bool `gorm:\"serializer:json\"`\n}","handlingStrategy":"validation","validationCode":"// Reject non-struct, non-slice relation fields before migrate\nfunc validRelationKind(t reflect.Type) bool {\n    for t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice || t.Kind() == reflect.Array {\n        t = t.Elem()\n    }\n    return t.Kind() == reflect.Struct\n}","typeGuard":null,"tryCatchPattern":"if err := db.AutoMigrate(&User{}); err != nil && strings.Contains(err.Error(), \"unsupported data type\") {\n    return fmt.Errorf(\"check model fields for maps/scalars needing serializer or gorm:\\\": %w\", err)\n}","preventionTips":["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."],"tags":["gorm","schema","relation","data-type"],"backgroundTag":null,"analyzedSha":"1d6ce99528060be18a42be09aca8d39efcb47f28","analyzedAt":"2026-08-15T13:01:23.433Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}