{"record":{"id":"291d580b6b6992e5","repo":"geektutu/7days-golang","slug":"not-found","errorCode":null,"errorMessage":"NOT FOUND","messagePattern":"NOT FOUND","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gee-orm/day4-chain-operation/session/record.go","lineNumber":63,"sourceCode":"\t\t\tvalues = append(values, dest.FieldByName(name).Addr().Interface())\n\t\t}\n\t\tif err := rows.Scan(values...); err != nil {\n\t\t\treturn err\n\t\t}\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":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-orm/day4-chain-operation/session/record.go#L45-L81","documentation":"Sentinel error returned by Session.First when the query with LIMIT 1 matches no rows: destSlice has length 0, so there is no record to assign to the destination value. It indicates the requested first row does not exist, not a query failure.","triggerScenarios":"Calling session.First(&User{}, \"name = ?\", \"bob\") where no row with name='bob' exists; querying by a wrong primary key; querying a table before any record was inserted.","commonSituations":"Test fixtures not seeded before First(); string/number type mismatch in the WHERE clause (e.g. '1' vs 1); querying against the wrong table name derived from the struct; looking up a deleted record.","solutions":["Check err with errors.Is/strings equality against \"NOT FOUND\" and treat as an expected empty result, not a failure","Verify the WHERE condition values and that records were inserted before the lookup","Confirm the struct's table name matches where the data was written","Prefer inserting/upserting the record if the miss is unexpected in the workflow"],"exampleFix":"// before\nvar u User\nif err := s.First(&u, \"id = ?\", id); err != nil {\n    return err // crashes on legit misses\n}\n// after\nvar u User\nif err := s.First(&u, \"id = ?\", id); err != nil {\n    if err.Error() == \"NOT FOUND\" {\n        return ErrUserNotFound // domain-level handling\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"var count int64\n_ = s.Model(&User{}).Count(&count) // confirm table has rows before First","typeGuard":null,"tryCatchPattern":"var u User\nif err := s.First(&u, \"name = ?\", name); err != nil {\n    if err.Error() == \"NOT FOUND\" {\n        // empty-result path: create default or return 404\n        return handleMissing(name)\n    }\n    return err // real query failure\n}","preventionTips":["Seed fixtures before read tests","Compare against the exact \"NOT FOUND\" sentinel in error handling","Validate WHERE argument types (string vs int)","Wrap the sentinel in a typed ErrRecordNotFound"],"tags":["orm","sql","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"}