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

  1. Pick a different, unused username
  2. Check existence first (list/get member) and update the existing member instead of creating
  3. Handle errors.Is(err, types.ErrMemberAlreadyExists) in the API layer and return HTTP 409
  4. 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

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


AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01). Data as JSON: /api/errors/b19090b2153997a8. Report an issue: GitHub.