{"record":{"id":"bb3871dd3ead0f20","repo":"go-gorm/gorm","slug":"unsupported-data-type-s-s","errorCode":null,"errorMessage":"unsupported data type: %s.%s","messagePattern":"unsupported data type: (.+?)\\.(.+?)","errorType":"validation","errorClass":"ErrUnsupportedDataType","httpStatus":null,"severity":"error","filePath":"schema/schema.go","lineNumber":162,"sourceCode":"\tmodelType := reflect.ValueOf(dest).Type()\n\tif modelType.Kind() == reflect.Ptr {\n\t\tmodelType = modelType.Elem()\n\t}\n\n\tif modelType.Kind() != reflect.Struct {\n\t\tif modelType.Kind() == reflect.Interface {\n\t\t\tmodelType = reflect.Indirect(reflect.ValueOf(dest)).Elem().Type()\n\t\t}\n\n\t\tfor modelType.Kind() == reflect.Slice || modelType.Kind() == reflect.Array || modelType.Kind() == reflect.Ptr {\n\t\t\tmodelType = modelType.Elem()\n\t\t}\n\n\t\tif modelType.Kind() != reflect.Struct {\n\t\t\tif modelType.PkgPath() == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: %+v\", ErrUnsupportedDataType, dest)\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"%w: %s.%s\", ErrUnsupportedDataType, modelType.PkgPath(), modelType.Name())\n\t\t}\n\t}\n\n\t// Cache the Schema for performance,\n\t// Use the modelType or modelType + schemaTable (if it present) as cache key.\n\tvar schemaCacheKey interface{} = modelType\n\tif specialTableName != \"\" {\n\t\tschemaCacheKey = fmt.Sprintf(\"%p-%s\", modelType, specialTableName)\n\t}\n\n\t// Load exist schema cache, return if exists\n\tif v, ok := cacheStore.Load(schemaCacheKey); ok {\n\t\ts := v.(*Schema)\n\t\t// Wait for the initialization of other goroutines to complete\n\t\t<-s.initialized\n\t\treturn s, s.err\n\t}\n","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/go-gorm/gorm/blob/1d6ce99528060be18a42be09aca8d39efcb47f28/schema/schema.go#L144-L180","documentation":"Same non-struct destination rejection as its sibling, but for named types: the destination resolves to a non-struct kind with a non-empty PkgPath, so the error carries `pkgpath.TypeName` instead of the raw value — more actionable for user-defined types like `type Status int` or `type IDs []int`.","triggerScenarios":"AutoMigrate or Find on a named non-struct type: `type IDs []uint` then `db.AutoMigrate(IDs{})`; named map types (`type Meta map[string]any`) without Valuer/Scanner used as the destination.","commonSituations":"Custom scalar aliases mistaken for models; generic repositories where T is unconstrained and occasionally instantiated with a scalar; migrating code from ORMs that allowed primitive destinations.","solutions":["Move the named type onto a struct model as a field with a serializer or Valuer/Scanner.","Constrain generics with `T any` struct requirements or a compile-time `struct{ _ T }` assertion.","Read the pkg.Type in the message to identify exactly which type leaked in."],"exampleFix":"// before\ntype IDs []uint\nerr := db.AutoMigrate(&IDs{}) // non-struct named type\n\n// after\ntype Record struct {\n    ID  uint `gorm:\"primaryKey\"`\n    IDs IDs `gorm:\"serializer:json\"`\n}\nerr := db.AutoMigrate(&Record{})","handlingStrategy":"type-guard","validationCode":"// For dynamically sourced models, verify named struct kind\nfunc isNamedStruct(dest any) bool {\n    t := reflect.TypeOf(dest)\n    for t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice || t.Kind() == reflect.Array { t = t.Elem() }\n    return t.Kind() == reflect.Struct && t.PkgPath() != \"\" || t.Kind() == reflect.Struct\n}","typeGuard":"func isModelType(t reflect.Type) bool {\n    for t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice || t.Kind() == reflect.Array { t = t.Elem() }\n    return t.Kind() == reflect.Struct\n}","tryCatchPattern":"if err := db.AutoMigrate(dest).Error; err != nil {\n    if errors.Is(err, schema.ErrUnsupportedDataType) {\n        return fmt.Errorf(\"%T is a named non-struct type; wrap it in a struct model\", dest)\n    }\n    return err\n}","preventionTips":["Wrap scalar aliases as fields on real models with serializers.","Add compile-time struct constraints in generic repositories.","The pkg.Type in the message names the culprit — audit that type's usage."],"tags":["gorm","reflection","parse","named-type"],"backgroundTag":null,"analyzedSha":"1d6ce99528060be18a42be09aca8d39efcb47f28","analyzedAt":"2026-08-15T13:01:23.433Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}