geektutu/7days-golang · warning

NOT FOUND

Error message

NOT FOUND

What it means

Sentinel error returned by Session.First when the LIMIT 1 query (with AfterQuery hooks already applied to fetched rows) yields an empty result set. It means no row matched the session's chain conditions; the destination value is left unset.

Source

Thrown at gee-orm/day5-hooks/session/record.go:66

		}
		if err := rows.Scan(values...); err != nil {
			return err
		}
		s.CallMethod(AfterQuery, dest.Addr().Interface())
		destSlice.Set(reflect.Append(destSlice, dest))
	}
	return rows.Close()
}

// First gets the 1st row
func (s *Session) First(value interface{}) error {
	dest := reflect.Indirect(reflect.ValueOf(value))
	destSlice := reflect.New(reflect.SliceOf(dest.Type())).Elem()
	if err := s.Limit(1).Find(destSlice.Addr().Interface()); err != nil {
		return err
	}
	if destSlice.Len() == 0 {
		return errors.New("NOT FOUND")
	}
	dest.Set(destSlice.Index(0))
	return nil
}

// Limit adds limit condition to clause
func (s *Session) Limit(num int) *Session {
	s.clause.Set(clause.LIMIT, num)
	return s
}

// Where adds limit condition to clause
func (s *Session) Where(desc string, args ...interface{}) *Session {
	var vars []interface{}
	s.clause.Set(clause.WHERE, append(append(vars, desc), args...)...)
	return s
}

View on GitHub (pinned to cf36443821)

Solutions

  1. Treat the sentinel as an empty-result signal and branch on it
  2. Verify hooks/conditions aren't excluding the row you expect
  3. Seed data or relax the WHERE condition
  4. Wrap it in a typed ErrRecordNotFound for cleaner handling

Example fix

// before
err := s.First(&u)
// after
var ErrRecordNotFound = errors.New("NOT FOUND")
if errors.Is(err, ErrRecordNotFound) { /* create or 404 */ }
Defensive patterns

Strategy: try-catch

Validate before calling

var users []User
if err := s.Find(&users); err == nil && len(users) == 0 { /* will be NOT FOUND */ }

Try / catch

if err := s.First(&u, hooks...); err != nil {
    if err.Error() == "NOT FOUND" { return errNotFound }
    return err
}

Prevention

When it happens

Trigger: First(&dest, cond) with no matching rows; after-hooks filtering rows conceptually; querying before seed data exists.

Common situations: Unseeded test DB; soft-deleted rows excluded by hook-added conditions; wrong condition arguments.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03). Data as JSON: /api/errors/83a69d68ed9192e8. Report an issue: GitHub.