{"record":{"id":"1814748616a8dd5d","repo":"m1k1o/neko","slug":"password-can-only-be-modified-in-config-while-in-m","errorCode":null,"errorMessage":"password can only be modified in config while in multiuser mode","messagePattern":"password can only be modified in config while in multiuser mode","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/member/multiuser/provider.go","lineNumber":69,"sourceCode":"\t\tif profile.Name == \"\" {\n\t\t\tprofile.Name = username\n\t\t}\n\t\treturn id, profile, nil\n\t}\n\n\treturn \"\", types.MemberProfile{}, types.ErrMemberInvalidPassword\n}\n\nfunc (provider *MemberProviderCtx) Insert(username string, password string, profile types.MemberProfile) (string, error) {\n\treturn \"\", errors.New(\"new user is created on first login in multiuser mode\")\n}\n\nfunc (provider *MemberProviderCtx) UpdateProfile(id string, profile types.MemberProfile) error {\n\treturn nil\n}\n\nfunc (provider *MemberProviderCtx) UpdatePassword(id string, password string) error {\n\treturn errors.New(\"password can only be modified in config while in multiuser mode\")\n}\n\nfunc (provider *MemberProviderCtx) Select(id string) (types.MemberProfile, error) {\n\treturn types.MemberProfile{}, errors.New(\"cannot select user in multiuser mode\")\n}\n\nfunc (provider *MemberProviderCtx) SelectAll(limit int, offset int) (map[string]types.MemberProfile, error) {\n\treturn map[string]types.MemberProfile{}, nil\n}\n\nfunc (provider *MemberProviderCtx) Delete(id string) error {\n\treturn errors.New(\"cannot delete user in multiuser mode\")\n}\n","sourceCodeStart":51,"sourceCodeEnd":83,"githubUrl":"https://github.com/m1k1o/neko/blob/b0f01cedea68893e85a3fd852c0521238c285695/server/internal/member/multiuser/provider.go#L51-L83","documentation":"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.","triggerScenarios":"Any call to the member UpdatePassword API (e.g. admin password-reset endpoint) while the member provider is 'multiuser'.","commonSituations":"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.","solutions":["Change the user's password in the server config (multiuser user entries) and restart/reload the server.","Switch to a dynamic member provider if runtime password management is needed.","Have client code detect multiuser mode and surface a 'edit config instead' message rather than calling UpdatePassword."],"exampleFix":"// before\nerr := memberClient.UpdatePassword(id, newPassword)\n\n// after: update password in config\n// NEKO_MEMBERS_MULTIUSER_USER_LIST='user1:newpass'\n// then reload the server\nif memberProvider == \"multiuser\" {\n    return errors.New(\"edit multiuser config to change password\")\n}","handlingStrategy":"validation","validationCode":"if memberProvider == \"multiuser\" {\n    return errors.New(\"passwords are config-managed in multiuser mode\")\n}\nerr := memberClient.UpdatePassword(id, newPassword)","typeGuard":"func isConfigManagedPasswordErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"modified in config\")\n}","tryCatchPattern":"err := memberClient.UpdatePassword(id, newPassword)\nif err != nil {\n    if isConfigManagedPasswordErr(err) {\n        log.Printf(\"change password in config and reload: %v\", err)\n    }\n    return err\n}","preventionTips":["Hide password-change forms when the member provider is multiuser or noauth.","Keep multiuser credentials in a managed config (env/config file) with a reload process.","Never rely on runtime password APIs for static providers.","Communicate config-reload requirements to operators changing passwords."],"tags":["multiuser","members","password","unsupported-operation","config"],"backgroundTag":"unsupported-operation-mode","analyzedSha":"b0f01cedea68893e85a3fd852c0521238c285695","analyzedAt":"2026-09-01T10:35:56.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}