{"record":{"id":"e9f5db0da372293a","repo":"go-gorm/gorm","slug":"failed-to-get-schema","errorCode":null,"errorMessage":"failed to get schema","messagePattern":"failed to get schema","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"migrator/migrator.go","lineNumber":133,"sourceCode":"\t\tqueryTx.DryRun = false\n\t\texecTx = m.DB.Session(&gorm.Session{Logger: &printSQLLogger{Interface: m.DB.Logger}})\n\t}\n\treturn queryTx, execTx\n}\n\n// AutoMigrate auto migrate values\nfunc (m Migrator) AutoMigrate(values ...interface{}) error {\n\tfor _, value := range m.ReorderModels(values, true) {\n\t\tqueryTx, execTx := m.GetQueryAndExecTx()\n\t\tif !queryTx.Migrator().HasTable(value) {\n\t\t\tif err := execTx.Migrator().CreateTable(value); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tif err := m.RunWithValue(value, func(stmt *gorm.Statement) error {\n\n\t\t\t\tif stmt.Schema == nil {\n\t\t\t\t\treturn errors.New(\"failed to get schema\")\n\t\t\t\t}\n\n\t\t\t\tcolumnTypes, err := queryTx.Migrator().ColumnTypes(value)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tvar (\n\t\t\t\t\tparseIndexes          = stmt.Schema.ParseIndexes()\n\t\t\t\t\tparseCheckConstraints = stmt.Schema.ParseCheckConstraints()\n\t\t\t\t)\n\t\t\t\tfor _, dbName := range stmt.Schema.DBNames {\n\t\t\t\t\tvar foundColumn gorm.ColumnType\n\n\t\t\t\t\tfor _, columnType := range columnTypes {\n\t\t\t\t\t\tif columnType.Name() == dbName {\n\t\t\t\t\t\t\tfoundColumn = columnType\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/go-gorm/gorm/blob/1d6ce99528060be18a42be09aca8d39efcb47f28/migrator/migrator.go#L115-L151","documentation":"During AutoMigrate, GORM runs RunWithValue to parse the model into a *schema.Statement. If stmt.Schema is nil after parsing, it returns errors.New(\"failed to get schema\"). A nil schema means the value you passed could not be interpreted as a model struct at all, so migration cannot proceed for it.","triggerScenarios":"Calling db.AutoMigrate with a value that schema.Parse cannot handle: a non-struct (string table name, map, int), a nil pointer, a pointer-to-pointer, or a struct whose fields all fail to parse. ReorderModels only reorders; it does not validate.","commonSituations":"Passing &[]User{} or User{} where a *User was expected; passing a table name string ('users') instead of a model; passing an interface{} holding nil from dynamic registration code; refactoring models so an embedded type became invalid.","solutions":["Pass a pointer to a plain struct: db.AutoMigrate(&User{}, &Order{}).","Remove nil values from the slice of models before calling AutoMigrate.","If migrating by table name was intended, use the Migrator SQL APIs (HasTable/CreateTable with a model) instead - AutoMigrate needs a model type.","Log reflect.TypeOf(value) for each value to find the offending entry."],"exampleFix":"// before\ndb.AutoMigrate(\"users\", &User{})\n\n// after\ndb.AutoMigrate(&User{})","handlingStrategy":"validation","validationCode":"func validateModels(values ...interface{}) error {\n    for _, v := range values {\n        rv := reflect.Indirect(reflect.ValueOf(v))\n        if !rv.IsValid() || rv.Kind() != reflect.Struct {\n            return fmt.Errorf(\"automigrate: %T is not a struct pointer\", v)\n        }\n    }\n    return nil\n}\n// call before db.AutoMigrate(...)","typeGuard":"func isStructPointer(v interface{}) bool {\n    rv := reflect.ValueOf(v)\n    return rv.Kind() == reflect.Ptr && rv.Elem().Kind() == reflect.Struct\n}","tryCatchPattern":"if err := db.AutoMigrate(models...); err != nil {\n    if strings.Contains(err.Error(), \"failed to get schema\") {\n        log.Printf(\"automigrate got a non-struct model; got %v\", models)\n    }\n    return err\n}","preventionTips":["Always pass &Struct{} literals to AutoMigrate; never table names or nil.","Lint migration call sites in code review - the argument list is the contract.","In dynamic registration code, assert types before collecting the model list."],"tags":["gorm","migration","automigrate","schema","api-misuse"],"backgroundTag":null,"analyzedSha":"1d6ce99528060be18a42be09aca8d39efcb47f28","analyzedAt":"2026-08-15T13:01:23.433Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}