AdguardTeam/AdGuardHome · error
userid: %w
Error message
userid: %w
What it means
Create rejected a user record because its UserID is the zero value; the wrapped sentinel is errors.ErrEmptyValue. The in-memory user database requires every created user to have a non-empty identifier.
Source
Thrown at internal/aghuser/db.go:132
func (db *DefaultDB) ByUUID(ctx context.Context, id UserID) (u *User, err error) {
db.mu.Lock()
defer db.mu.Unlock()
u, ok := db.userIDToUser[id]
if !ok {
return nil, nil
}
return u, nil
}
// Create implements the [DB] interface for *DefaultDB.
func (db *DefaultDB) Create(ctx context.Context, u *User) (err error) {
db.mu.Lock()
defer db.mu.Unlock()
if u.ID == (UserID{}) {
return fmt.Errorf("userid: %w", errors.ErrEmptyValue)
}
_, ok := db.userIDToUser[u.ID]
if ok {
return fmt.Errorf("userid: %w", errors.ErrDuplicated)
}
_, ok = db.loginToUserID[u.Login]
if ok {
return fmt.Errorf("login: %w", errors.ErrDuplicated)
}
db.userIDToUser[u.ID] = u
db.loginToUserID[u.Login] = u.ID
return nil
}
View on GitHub (pinned to b41aefbe51)
Solutions
- Generate an ID before calling Create, e.g. u.ID = aghuser.NewUserID()
- If importing users, map each source user to a fresh UserID
- Add a lint/test that asserts u.ID != UserID{} before persistence
Example fix
// before
err := db.Create(ctx, &aghuser.User{Login: "alice"})
// after
u := &aghuser.User{Login: "alice"}
u.ID = aghuser.NewUserID()
err := db.Create(ctx, u) Defensive patterns
Strategy: validation
Validate before calling
if u.ID == (aghuser.UserID{}) {
u.ID = aghuser.NewUserID()
} Type guard
func hasUserID(u *aghuser.User) bool { return u.ID != aghuser.UserID{} } Try / catch
if err := db.Create(ctx, u); err != nil {
if errors.Is(err, errors.ErrEmptyValue) { u.ID = aghuser.NewUserID(); err = db.Create(ctx, u) }
} Prevention
- Centralize user construction in one factory that always assigns an ID
- Assert non-zero ID in tests before persistence
When it happens
Trigger: Calling DefaultDB.Create with a User whose ID field was never set (u.ID == UserID{}), typically when the caller expects the DB to autogenerate IDs — it does not.
Common situations: Building users from parsed config or requests without generating an ID first; refactors that dropped the ID assignment; test fixtures forgetting to set an ID.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- login: %w
- json time is nil
- interface %s has no ipv6 addresses
- invalid ip version %d
- could not find hardware port for %s
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/e03d933663dd4b17.
Report an issue: GitHub.