{"record":{"id":"3df420ae487ca1b2","repo":"plandex-ai/plandex","slug":"project-does-not-exist-in-org","errorCode":null,"errorMessage":"project does not exist in org","messagePattern":"project does not exist in org","errorType":"http","errorClass":null,"httpStatus":404,"severity":"error","filePath":"app/server/handlers/auth_helpers.go","lineNumber":634,"sourceCode":"\nfunc authorizeProject(w http.ResponseWriter, projectId string, auth *types.ServerAuth) bool {\n\treturn authorizeProjectOptional(w, projectId, auth, true)\n}\n\nfunc authorizeProjectOptional(w http.ResponseWriter, projectId string, auth *types.ServerAuth, shouldErr bool) bool {\n\tlog.Println(\"authorizing project\")\n\n\tprojectExists, err := db.ProjectExists(auth.OrgId, projectId)\n\n\tif err != nil {\n\t\tlog.Printf(\"error validating project: %v\\n\", err)\n\t\thttp.Error(w, \"error validating project\", http.StatusInternalServerError)\n\t\treturn false\n\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","sourceCodeStart":616,"sourceCodeEnd":652,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/auth_helpers.go#L616-L652","documentation":"This 404 is returned by authorizeProjectOptional when db.ProjectExists reports the projectId does not exist in the caller's organization. It means the project either truly does not exist, was deleted/archived, or belongs to a different org than the authenticated user's. shouldErr=true via authorizeProject makes this response mandatory; authorizeProjectOptional with shouldErr=false returns false silently instead.","triggerScenarios":"Calling any project-scoped endpoint (via authorizeProject, RenameProjectHandler, DeleteProjectHandler, ListPlansHandler) with a projectId that is not a row in the projects table for auth.OrgId — wrong ID, typo, deleted project, or project belonging to another org.","commonSituations":"Client caching a stale projectId after the project was deleted; using an ID from a different organization; a copy-paste or truncation error in the ID; switching orgs in the client but reusing the old project ID.","solutions":["Verify the projectId in the request matches an existing project in the authenticated organization","List projects via the org's projects endpoint and use a valid projectId","Confirm the client is authenticated against the same org that owns the project","If the project was recently deleted, recreate it or pick another project"],"exampleFix":"// before\nawait api.renameProject({ projectId: localStorage.projectId, name: 'new-name' });\n// after\nconst projects = await api.listProjects();\nconst project = projects.find(p => p.id === localStorage.projectId);\nif (!project) throw new Error(`Project ${localStorage.projectId} not found in org; refresh project list`);\nawait api.renameProject({ projectId: project.id, name: 'new-name' });","handlingStrategy":"validation","validationCode":"async function ensureProjectExistsInOrg(orgId, projectId) {\n  const projects = await api.listProjects(orgId);\n  if (!projects.some(p => p.id === projectId)) {\n    throw new Error(`Project ${projectId} does not exist in org ${orgId}; refresh and pick a valid project`);\n  }\n}","typeGuard":"function isProjectNotFound(res) {\n  return res.status === 404 && res.headers.get('content-type')?.includes('text/plain');\n}","tryCatchPattern":"try {\n  const res = await fetch(`/api/projects/${projectId}/plans`, { headers: authHeaders });\n  if (res.status === 404) {\n    const text = await res.text();\n    if (text === 'project does not exist in org') {\n      // refresh project list, clear stale cached ID\n      await refreshProjectList();\n      return null;\n    }\n  }\n  return await res.json();\n} catch (e) { throw e; }","preventionTips":["Always resolve projectId from a fresh list-projects call, never long-lived caches","Include org scoping when storing/selecting project IDs in the client","Purge or revalidate cached project IDs after delete operations","Log the projectId and orgId together to catch cross-org mix-ups quickly"],"tags":["http-404","authorization","project-not-found","go"],"backgroundTag":"resource-not-found","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"}