m1k1o/neko · error

password can only be modified in config while in multiuser m

Error message

password can only be modified in config while in multiuser mode

What it means

In multiuser mode member passwords are defined statically in the config file, so the provider refuses to change a password at runtime. UpdatePassword() is a stub that always returns this error, signaling that password changes must go through the config, not the API.

Source

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

		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
}

func (provider *MemberProviderCtx) Delete(id string) error {
	return errors.New("cannot delete user in multiuser mode")
}

View on GitHub (pinned to b0f01cedea)

Solutions

  1. Change the user's password in the server config (multiuser user entries) and restart/reload the server.
  2. Switch to a dynamic member provider if runtime password management is needed.
  3. Have client code detect multiuser mode and surface a 'edit config instead' message rather than calling UpdatePassword.

Example fix

// before
err := memberClient.UpdatePassword(id, newPassword)

// after: update password in config
// NEKO_MEMBERS_MULTIUSER_USER_LIST='user1:newpass'
// then reload the server
if memberProvider == "multiuser" {
    return errors.New("edit multiuser config to change password")
}
Defensive patterns

Strategy: validation

Validate before calling

if memberProvider == "multiuser" {
    return errors.New("passwords are config-managed in multiuser mode")
}
err := memberClient.UpdatePassword(id, newPassword)

Type guard

func isConfigManagedPasswordErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "modified in config")
}

Try / catch

err := memberClient.UpdatePassword(id, newPassword)
if err != nil {
    if isConfigManagedPasswordErr(err) {
        log.Printf("change password in config and reload: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Any call to the member UpdatePassword API (e.g. admin password-reset endpoint) while the member provider is 'multiuser'.

Common situations: An operator or admin UI attempts to reset a member's password at runtime; in multiuser deployments passwords live in config (MULTIUSER user entries), so every such call fails.

Related errors


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