m1k1o/neko · error
ErrMemberAlreadyExists
ErrMemberAlreadyExists
Error message
member already exists
What it means
ErrMemberAlreadyExists is a sentinel error returned when inserting a member whose username/ID already exists in the member store (membersCreate -> Insert). The members repository enforces uniqueness, so creating a duplicate user is rejected with this error.
Source
Thrown at server/pkg/types/member.go:6
package types
import "errors"
var (
ErrMemberAlreadyExists = errors.New("member already exists")
ErrMemberDoesNotExist = errors.New("member does not exist")
ErrMemberInvalidPassword = errors.New("invalid password")
)
type MemberProfile struct {
Name string `json:"name"`
// permissions
IsAdmin bool `json:"is_admin" mapstructure:"is_admin"`
CanLogin bool `json:"can_login" mapstructure:"can_login"`
CanConnect bool `json:"can_connect" mapstructure:"can_connect"`
CanWatch bool `json:"can_watch" mapstructure:"can_watch"`
CanHost bool `json:"can_host" mapstructure:"can_host"`
CanShareMedia bool `json:"can_share_media" mapstructure:"can_share_media"`
CanAccessClipboard bool `json:"can_access_clipboard" mapstructure:"can_access_clipboard"`
SendsInactiveCursor bool `json:"sends_inactive_cursor" mapstructure:"sends_inactive_cursor"`
CanSeeInactiveCursors bool `json:"can_see_inactive_cursors" mapstructure:"can_see_inactive_cursors"`
View on GitHub (pinned to b0f01cedea)
Solutions
- Pick a different, unused username
- Check existence first (list/get member) and update the existing member instead of creating
- Handle errors.Is(err, types.ErrMemberAlreadyExists) in the API layer and return HTTP 409
- Deduplicate your import data against the current member list before inserting
Example fix
// before
err := members.Insert(username, password, profile)
if err != nil { return err }
// after
err := members.Insert(username, password, profile)
if errors.Is(err, types.ErrMemberAlreadyExists) {
return http.StatusConflict, "user already exists"
}
if err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
_, err := members.Get(username)
if err == nil {
// member exists; update instead of insert
} Type guard
func memberExists(m types.Members, username string) bool {
_, err := m.Get(username)
return err == nil
} Try / catch
err := members.Insert(username, password, profile)
if errors.Is(err, types.ErrMemberAlreadyExists) {
// return 409 or update the existing member
} Prevention
- Uniqueness-check the username in the UI before submit
- Use errors.Is with the sentinel error, not string comparison
- Handle duplicates on import by upserting
- Return HTTP 409 from the API on this sentinel error
When it happens
Trigger: POST /members (membersCreate) with a username that already exists; concurrent creation of the same user; importing/restoring members into a non-empty store without clearing duplicates.
Common situations: Admin re-running a user-creation script; registering a username someone else took; data import colliding with existing users; retrying a request that actually succeeded the first time.
Related errors
- new user is created on first login in multiuser mode
- password can only be modified in config while in multiuser m
- cannot select user in multiuser mode
- cannot delete user in multiuser mode
- new user is created on first login in noauth mode
AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01).
Data as JSON: /api/errors/b19090b2153997a8.
Report an issue: GitHub.