{"record":{"id":"a7857974c09e11be","repo":"go-gorm/gorm","slug":"unsupported-data-type-v","errorCode":null,"errorMessage":"unsupported data type: %+v","messagePattern":"unsupported data type: %\\+v","errorType":"validation","errorClass":"ErrUnsupportedDataType","httpStatus":null,"severity":"error","filePath":"schema/schema.go","lineNumber":141,"sourceCode":"}\n\nvar callbackTypes = []callbackType{\n\tcallbackTypeBeforeCreate, callbackTypeAfterCreate,\n\tcallbackTypeBeforeUpdate, callbackTypeAfterUpdate,\n\tcallbackTypeBeforeSave, callbackTypeAfterSave,\n\tcallbackTypeBeforeDelete, callbackTypeAfterDelete,\n\tcallbackTypeAfterFind,\n}\n\n// Parse get data type from dialector\nfunc Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) {\n\treturn ParseWithSpecialTableName(dest, cacheStore, namer, \"\")\n}\n\n// ParseWithSpecialTableName get data type from dialector with extra schema table\nfunc ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Namer, specialTableName string) (*Schema, error) {\n\tif dest == nil {\n\t\treturn nil, fmt.Errorf(\"%w: %+v\", ErrUnsupportedDataType, dest)\n\t}\n\n\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() == \"\" {","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/go-gorm/gorm/blob/1d6ce99528060be18a42be09aca8d39efcb47f28/schema/schema.go#L123-L159","documentation":"ParseWithSpecialTableName rejects a nil destination outright with the ErrUnsupportedDataType sentinel wrapped around the value. Passing a nil model (typed nil pointers included, since dest == nil only catches truly nil interface) means GORM has nothing to reflect on. The error is wrapped with %w so errors.Is(err, schema.ErrUnsupportedDataType) works.","triggerScenarios":"Calling db.AutoMigrate(nil), db.Find(nil), or passing a nil interface{} model variable — commonly a nil slice header or a model variable that was never initialized.","commonSituations":"Passing a nil pointer from optional request params; test helpers with unset model variables; reflection-driven code that passes a nil interface{} dynamically.","solutions":["Initialize the model before passing: `var users []User; db.Find(&users)`.","Guard call sites where the model may legitimately be nil and skip the GORM call.","Check errors.Is(err, schema.ErrUnsupportedDataType) to give a clear message in wrappers."],"exampleFix":"// before\nvar user *User // nil\nerr := db.First(user).Error\n\n// after\nvar user User\nerr := db.First(&user).Error","handlingStrategy":"type-guard","validationCode":"if dest == nil {\n    return errors.New(\"model must not be nil\")\n}\n// or: ensure pointer to initialized struct before calling GORM","typeGuard":"func isNonNilStructPtr(v any) bool {\n    if v == nil { return false }\n    rv := reflect.ValueOf(v)\n    return rv.Kind() == reflect.Ptr && !rv.IsNil() && rv.Elem().Kind() == reflect.Struct\n}","tryCatchPattern":"if err := db.AutoMigrate(model).Error; err != nil {\n    if errors.Is(err, schema.ErrUnsupportedDataType) {\n        return fmt.Errorf(\"model was nil or not a struct: %w\", err)\n    }\n    return err\n}","preventionTips":["Always pass &Model{} (never a nil variable) to AutoMigrate/Find.","Check optional models for nil before DB calls.","Match on the ErrUnsupportedDataType sentinel in wrappers."],"tags":["gorm","nil","parse","validation"],"backgroundTag":null,"analyzedSha":"1d6ce99528060be18a42be09aca8d39efcb47f28","analyzedAt":"2026-08-15T13:01:23.433Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}