{"record":{"id":"47f13b562afec4f0","repo":"plandex-ai/plandex","slug":"not-a-member-of-org","errorCode":null,"errorMessage":"not a member of org","messagePattern":"not a member of org","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"app/server/handlers/auth_helpers.go","lineNumber":562,"sourceCode":"\t\t}\n\n\t\tif invite != nil {\n\t\t\tlog.Println(\"accepting invite\")\n\n\t\t\terr := db.AcceptInvite(r.Context(), invite, authToken.UserId)\n\n\t\t\tif err != nil {\n\t\t\t\tlog.Printf(\"error accepting invite: %v\\n\", err)\n\t\t\t\tif raiseErr {\n\t\t\t\t\thttp.Error(w, \"error accepting invite\", http.StatusInternalServerError)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t} else {\n\t\t\tlog.Println(\"user is not a member of the org\")\n\t\t\tif raiseErr {\n\t\t\t\thttp.Error(w, \"not a member of org\", http.StatusUnauthorized)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t}\n\n\t// get user permissions\n\tpermissions, err := db.GetUserPermissions(authToken.UserId, parsed.OrgId)\n\n\tif err != nil {\n\t\tlog.Printf(\"error getting user permissions: %v\\n\", err)\n\t\tif raiseErr {\n\t\t\thttp.Error(w, \"error getting user permissions\", http.StatusInternalServerError)\n\t\t}\n\t\treturn nil\n\t}\n\n\t// build the permissions map\n\tpermissionsMap := make(shared.Permissions)","sourceCodeStart":544,"sourceCodeEnd":580,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/auth_helpers.go#L544-L580","documentation":"The user is not a member of the requested org and no active invite exists to auto-accept, so the server logs 'not a member of org' and returns HTTP 401 when raiseErr is true. This is a policy denial: valid user, valid token, no access to that org.","triggerScenarios":"Authenticated request whose parsed.OrgId belongs to an org the user never joined and for which GetActiveInviteByEmail returns no invite.","commonSituations":"User typing/selecting the wrong org id; calling another company's org endpoint; org membership revoked while the client still has the org selected; stale cached org id after leaving an org.","solutions":["Verify the OrgId in the request matches an org the user actually belongs to","Request an invitation to the org or have an admin add the user","Re-fetch the user's org list and switch the client to a valid org","Clear stale org selection in the client if membership was revoked"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"orgs, err := client.ListMyOrgs(ctx)\nif err != nil {\n\treturn err\n}\nif !slices.ContainsFunc(orgs, func(o Org) bool { return o.ID == orgID }) {\n\treturn fmt.Errorf(\"org %s: not a member; request an invite first\", orgID)\n}","typeGuard":"func hasOrgAccess(orgs []Org, orgID string) bool {\n\tfor _, o := range orgs {\n\t\tif o.ID == orgID {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","tryCatchPattern":"if err := doCall(ctx); err != nil {\n\tvar apiErr *APIError\n\tif errors.As(err, &apiErr) && apiErr.StatusCode == 401 && strings.Contains(apiErr.Message, \"not a member of org\") {\n\t\treturn switchToValidOrgOrRequestInvite()\n\t}\n\treturn err\n}","preventionTips":["Validate the org id against the user's org list before calls","Refresh cached org selections after membership changes","Request an invite before attempting org-scoped operations","Handle 401 by prompting org selection instead of retrying blindly"],"tags":["auth","org","forbidden","permissions"],"backgroundTag":"not-a-member-of-org","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"}