{"record":{"id":"a74203e82c76d42c","repo":"plandex-ai/plandex","slug":"user-does-not-have-permission-to-rename-project","errorCode":null,"errorMessage":"User does not have permission to rename project","messagePattern":"User does not have permission to rename project","errorType":"http","errorClass":null,"httpStatus":403,"severity":"warning","filePath":"app/server/handlers/auth_helpers.go","lineNumber":648,"sourceCode":"\t}\n\n\tif !projectExists && shouldErr {\n\t\tlog.Println(\"project does not exist in org\")\n\t\thttp.Error(w, \"project does not exist in org\", http.StatusNotFound)\n\t\treturn false\n\t}\n\n\treturn projectExists\n}\n\nfunc authorizeProjectRename(w http.ResponseWriter, projectId string, auth *types.ServerAuth) bool {\n\tif !authorizeProject(w, projectId, auth) {\n\t\treturn false\n\t}\n\n\tif !auth.HasPermission(shared.PermissionRenameAnyProject) {\n\t\tlog.Println(\"User does not have permission to rename project\")\n\t\thttp.Error(w, \"User does not have permission to rename project\", http.StatusForbidden)\n\t\treturn false\n\t}\n\n\treturn true\n}\n\nfunc authorizeProjectDelete(w http.ResponseWriter, projectId string, auth *types.ServerAuth) bool {\n\tif !authorizeProject(w, projectId, auth) {\n\t\treturn false\n\t}\n\n\tif !auth.HasPermission(shared.PermissionDeleteAnyProject) {\n\t\tlog.Println(\"User does not have permission to delete project\")\n\t\thttp.Error(w, \"User does not have permission to delete project\", http.StatusForbidden)\n\t\treturn false\n\t}\n\n\treturn true","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/auth_helpers.go#L630-L666","documentation":"This 403 is returned by authorizeProjectRename after authorizeProject succeeds but the authenticated user lacks the shared.PermissionRenameAnyProject permission. The project exists in the org, but only users holding that permission may rename projects; ordinary members are denied. It is an explicit authorization failure, not an authentication one.","triggerScenarios":"RenameProjectHandler invoked by a user whose auth context does not include PermissionRenameAnyProject — typically a regular org member rather than an owner/admin attempting PUT/rename on a project.","commonSituations":"A member tries to rename a team project they didn't create; role changes removed the permission but the client UI still shows the rename action; API token scoped with reduced permissions used in scripts.","solutions":["Ask an org owner/admin to grant the PermissionRenameAnyProject permission (or a role that includes it) to the user","Have a user who already holds the permission perform the rename","Check the client UI to hide/disable rename actions for users lacking the permission","If using API tokens, regenerate the token with the rename-project scope"],"exampleFix":"// before (server): any project member could rename\nif !auth.HasPermission(shared.PermissionRenameAnyProject) {\n\thttp.Error(w, \"User does not have permission to rename project\", http.StatusForbidden)\n\treturn false\n}\n// after (client): check permission before offering rename\nif (auth.permissions.includes('rename_any_project')) {\n  showRenameButton(project);\n} else {\n  console.warn('Rename requires the rename-any-project permission');\n}","handlingStrategy":"type-guard","validationCode":"function canRenameProjects(auth) {\n  return auth.user.role === 'owner' || auth.user.role === 'admin' ||\n         auth.permissions.includes('rename_any_project');\n}","typeGuard":"function hasPermission(auth, perm) {\n  return Array.isArray(auth?.permissions) && auth.permissions.includes(perm);\n}","tryCatchPattern":"try {\n  const res = await api.renameProject(projectId, newName);\n  return res;\n} catch (e) {\n  if (e.status === 403 && /permission to rename project/.test(e.body)) {\n    notifyUser('You need the rename-any-project permission to rename this project');\n    return null;\n  }\n  throw e;\n}","preventionTips":["Check auth.permissions before rendering rename controls","Keep client role metadata in sync with server permission grants","Test rename flows with non-admin accounts","Use scoped API tokens that match the operations the script performs"],"tags":["http-403","authorization","permissions","rbac"],"backgroundTag":"insufficient-permissions","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}