{"record":{"id":"80a3c922e5f3e3b2","repo":"1Panel-dev/1Panel","slug":"failed-to-update-mongodb-user-privileges","errorCode":null,"errorMessage":"failed to update mongodb user privileges","messagePattern":"failed to update mongodb user privileges","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"agent/app/service/database_mongodb.go","lineNumber":804,"sourceCode":"const userInfo = targetDb.runCommand({\n  usersInfo: userName,\n  showCredentials: false,\n  showCustomData: false\n});\nif (!userInfo || userInfo.ok !== 1) {\n  throw new Error(\"failed to load mongodb user privileges\");\n}\nif (!Array.isArray(userInfo.users) || userInfo.users.length === 0) {\n  throw new Error(\"mongodb user not found: \" + userName);\n}\nconst roles = (userInfo.users[0].roles || []).filter(role => role.db !== dbName);\nroles.push({ role: permission, db: dbName });\nconst result = targetDb.runCommand({\n  updateUser: userName,\n  roles: roles\n});\nif (!result || result.ok !== 1) {\n  throw new Error(\"failed to update mongodb user privileges\");\n}\n`, databaseJSON, usernameJSON, permissionJSON))\n\treturn runMongodbAdminScript(connectionName, script)\n}\n\nfunc loadRemoteMongodbPrivilege(connectionName, dbName, username string) (string, error) {\n\tinfo, err := loadRemoteMongodbConnection(connectionName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tclient, ctx, cancel, err := newRemoteMongodbClient(info)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer cancel()\n\tdefer client.Disconnect(ctx)\n\n\ttargetDB := client.Database(dbName)","sourceCodeStart":786,"sourceCodeEnd":822,"githubUrl":"https://github.com/1Panel-dev/1Panel/blob/5ac7c808815b0691009cd390414f03471312262f/agent/app/service/database_mongodb.go#L786-L822","documentation":"Final step of the privilege-change script (database_mongodb.go:804): `updateUser` with the merged roles array returned ok !== 1. The roles array was built by filtering the user's existing roles and pushing `{ role: permission, db: dbName }`, so failure usually means the permission string is not a recognized built-in role, the caller may not grant that role, or a role from another db survived the filter and cannot be re-granted here.","triggerScenarios":"Submitting a permission value that is not a valid role on that MongoDB (custom role not defined, typo like 'read_write'); the admin credential can modify the user but lacks grantRole for the requested permission; roles attached to other dbs cause updateUser to fail when re-granted on this db.","commonSituations":"Custom role names that exist on some deployments but not this one; version differences in role availability; least-privilege admin credentials.","solutions":["Run updateUser manually with the same roles array and read codeName — 'No role named <x>@<db>' pinpoints a bad permission value","Restrict the UI/input permission set to roles that exist on this server (`db.getSiblingDB(dbName).runCommand({rolesInfo:1, showBuiltinRoles:true})`)","Grant the admin credential grantRole for the requested role, or use root","Drop stale cross-db roles for the user before changing permissions"],"exampleFix":"// validate before submit\n// const ok = db.getSiblingDB(\"mydb\")\n//   .runCommand({rolesInfo:\"readWrite\", showBuiltinRoles:true}).roles?.length > 0;","handlingStrategy":"validation","validationCode":"// validate the permission against the server's role catalog before submit\n// db.getSiblingDB(dbName).runCommand({rolesInfo:1, showBuiltinRoles:true}).roles\n// reject permission values not present in that catalog","typeGuard":"// Go: whitelist known-good roles before building the script\nvar mongodbBuiltinRoles = map[string]bool{\n    \"read\": true, \"readWrite\": true, \"dbAdmin\": true, \"dbOwner\": true,\n    \"readAnyDatabase\": true, \"readWriteAnyDatabase\": true, \"userAdminAnyDatabase\": true,\n}\nfunc validMongodbRole(p string) bool { return mongodbBuiltinRoles[p] }","tryCatchPattern":"if err := changePrivilege(...); err != nil && strings.Contains(err.Error(), \"failed to update mongodb user privileges\") {\n    // surface rolesInfo output so the user sees which role name is unknown\n}","preventionTips":["Drive the permission dropdown from rolesInfo instead of a hardcoded list","Run custom-role deployments with a credential holding grantRole"],"tags":["mongodb","updateuser","roles","validation"],"backgroundTag":null,"analyzedSha":"5ac7c808815b0691009cd390414f03471312262f","analyzedAt":"2026-08-15T14:02:06.953Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}