AdguardTeam/AdGuardHome · error

login: %w

Error message

login: %w

What it means

Create rejected a duplicate login name: another user already occupies u.Login, so the login-to-user mapping cannot be added (wrapped sentinel errors.ErrDuplicated). Logins are unique independent of IDs.

Source

Thrown at internal/aghuser/db.go:142

}

// 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

  1. Check for an existing user by login before creating and update it instead
  2. Choose a different, unique login for the new record
  3. Make import scripts skip-or-update on existing logins

Example fix

// before
db.Create(ctx, &User{ID: id2, Login: "alice"}) // alice exists
// after
db.Create(ctx, &User{ID: id2, Login: "alice2"})
Defensive patterns

Strategy: validation

Validate before calling

if _, exists, _ := db.UserByLogin(ctx, u.Login); exists {
    return fmt.Errorf("login %q taken", u.Login)
}

Try / catch

if err := db.Create(ctx, u); err != nil {
    if errors.Is(err, errors.ErrDuplicated) && strings.HasPrefix(err.Error(), "login") { u.Login += "2"; err = db.Create(ctx, u) }
}

Prevention

When it happens

Trigger: Calling DefaultDB.Create with a login string already present in db.loginToUserID — two accounts with the same username, or a re-run of user provisioning that does not dedupe by login.

Common situations: Renaming/creating a user with a username that already exists; retrying a partial import where the first attempt committed some users; case-sensitive collisions ('Alice' vs 'alice' both allowed, but exact matches collide).

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/04dcd762624cc080. Report an issue: GitHub.