{"record":{"id":"0f6ef67ad0fa06f8","repo":"geektutu/7days-golang","slug":"not-found-0f6ef6","errorCode":null,"errorMessage":"NOT FOUND","messagePattern":"NOT FOUND","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gee-orm/day7-migrate/session/record.go","lineNumber":66,"sourceCode":"\t\t}\n\t\tif err := rows.Scan(values...); err != nil {\n\t\t\treturn err\n\t\t}\n\t\ts.CallMethod(AfterQuery, dest.Addr().Interface())\n\t\tdestSlice.Set(reflect.Append(destSlice, dest))\n\t}\n\treturn rows.Close()\n}\n\n// First gets the 1st row\nfunc (s *Session) First(value interface{}) error {\n\tdest := reflect.Indirect(reflect.ValueOf(value))\n\tdestSlice := reflect.New(reflect.SliceOf(dest.Type())).Elem()\n\tif err := s.Limit(1).Find(destSlice.Addr().Interface()); err != nil {\n\t\treturn err\n\t}\n\tif destSlice.Len() == 0 {\n\t\treturn errors.New(\"NOT FOUND\")\n\t}\n\tdest.Set(destSlice.Index(0))\n\treturn nil\n}\n\n// Limit adds limit condition to clause\nfunc (s *Session) Limit(num int) *Session {\n\ts.clause.Set(clause.LIMIT, num)\n\treturn s\n}\n\n// Where adds limit condition to clause\nfunc (s *Session) Where(desc string, args ...interface{}) *Session {\n\tvar vars []interface{}\n\ts.clause.Set(clause.WHERE, append(append(vars, desc), args...)...)\n\treturn s\n}\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-orm/day7-migrate/session/record.go#L48-L84","documentation":"Sentinel error returned by Session.First (in the migrate-enabled session) when the LIMIT 1 query finds no rows. It is a not-found signal, distinct from SQL or scan errors, and the destination value stays untouched.","triggerScenarios":"First() after migrating a fresh schema (tables exist but are empty); querying rows against a renamed table after a migration changed the naming; stale conditions referencing dropped columns.","commonSituations":"Running AutoMigrate on a fresh DB then immediately reading expecting seeded data; migration renamed the table so old queries hit an empty legacy table.","solutions":["Seed data after AutoMigrate before querying","Check the table name/columns still match the struct after migrations","Handle the sentinel as empty-result and create the record if needed","Wrap into a typed not-found error for callers"],"exampleFix":"// before\nengine.AutoMigrate(&User{})\ns.First(&u) // empty table -> NOT FOUND\n// after\nengine.AutoMigrate(&User{})\ns.Insert(&User{Name: \"demo\"})\ns.First(&u)","handlingStrategy":"try-catch","validationCode":"has, _ := s.Model(&User{}).Count(&count); if count == 0 { seed() } // post-migrate seeding check","typeGuard":null,"tryCatchPattern":"if err := s.First(&u); err != nil {\n    if err.Error() == \"NOT FOUND\" { return seedAndRetry() }\n    return err\n}","preventionTips":["Always seed after AutoMigrate on fresh DBs","Re-check table/column names after schema changes","Treat \"NOT FOUND\" as empty result, not fatal","Add migration smoke tests with reads"],"tags":["orm","sql","migration","not-found"],"backgroundTag":"record-not-found","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}