m1k1o/neko · error

new user is created on first login in multiuser mode

Error message

new user is created on first login in multiuser mode

What it means

In multiuser mode members are defined statically in the config file, and the provider's Authenticate path creates users only on first login from that config. Insert() is therefore an unsupported operation by design: programmatically creating a new member is refused because new users are supposed to appear solely through first login against config-defined credentials.

Source

Thrown at server/internal/member/multiuser/provider.go:61

			profile.Name = username
		}
		return id, profile, nil
	}

	// if logged in as user
	if provider.config.UserPassword == password {
		profile := provider.config.UserProfile
		if profile.Name == "" {
			profile.Name = username
		}
		return id, profile, nil
	}

	return "", types.MemberProfile{}, types.ErrMemberInvalidPassword
}

func (provider *MemberProviderCtx) Insert(username string, password string, profile types.MemberProfile) (string, error) {
	return "", errors.New("new user is created on first login in multiuser mode")
}

func (provider *MemberProviderCtx) UpdateProfile(id string, profile types.MemberProfile) error {
	return nil
}

func (provider *MemberProviderCtx) UpdatePassword(id string, password string) error {
	return errors.New("password can only be modified in config while in multiuser mode")
}

func (provider *MemberProviderCtx) Select(id string) (types.MemberProfile, error) {
	return types.MemberProfile{}, errors.New("cannot select user in multiuser mode")
}

func (provider *MemberProviderCtx) SelectAll(limit int, offset int) (map[string]types.MemberProfile, error) {
	return map[string]types.MemberProfile{}, nil
}

View on GitHub (pinned to b0f01cedea)

Solutions

  1. Add the new user directly in the server config (multiuser user entries) and restart/reload the server; first login then creates the member.
  2. Switch the deployment to a dynamic member provider if runtime user creation is required.
  3. Adjust client tooling to treat multiuser mode as read-only and skip Insert calls (see provider.SelectAll/UpdateProfile which are no-ops).

Example fix

// before: trying to create a user via API in multiuser mode
id, err := memberClient.Insert(username, password, profile)

// after: add user to config instead
// config: NEKO_MEMBERS_MULTIUSER_USER_LIST='user1:pass1,user2:pass2'
// then let the user log in; Insert is unsupported:
if memberProvider == "multiuser" {
    return errors.New("add user to config; Insert is unsupported in multiuser mode")
}
Defensive patterns

Strategy: validation

Validate before calling

if memberProvider == "multiuser" {
    return errors.New("user creation unsupported in multiuser mode; add user to config")
}
id, err := memberClient.Insert(username, password, profile)

Type guard

func isModeUnsupportedErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "created on first login")
}

Try / catch

id, err := memberClient.Insert(username, password, profile)
if err != nil {
    if isModeUnsupportedErr(err) {
        log.Printf("add user to multiuser config instead: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Any call to the member-management Insert API (e.g. an admin users-create endpoint) while the server runs with member provider 'multiuser'.

Common situations: An operator builds admin tooling or scripts against the users API assuming a dynamic member store, but the deployment config uses multiuser mode where members come from config (MULTIUSER_USER/Pass entries); API calls to create users always fail with this message.

Related errors


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