{"record":{"id":"801c773750244f87","repo":"plandex-ai/plandex","slug":"error-listing-org-roles","errorCode":null,"errorMessage":"Error listing org roles: ","messagePattern":"Error listing org roles: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/orgs.go","lineNumber":237,"sourceCode":"\t\twriteApiError(w, shared.ApiError{\n\t\t\tType:   shared.ApiErrorTypeTrialActionNotAllowed,\n\t\t\tStatus: http.StatusForbidden,\n\t\t\tMsg:    \"Trial user can't list org roles\",\n\t\t})\n\t\treturn\n\t}\n\n\tif !auth.HasPermission(shared.PermissionListOrgRoles) {\n\t\tlog.Println(\"User cannot list org roles\")\n\t\thttp.Error(w, \"User cannot list org roles\", http.StatusForbidden)\n\t\treturn\n\t}\n\n\troles, err := db.ListOrgRoles(auth.OrgId)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error listing org roles: %v\\n\", err)\n\t\thttp.Error(w, \"Error listing org roles: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tvar apiRoles []*shared.OrgRole\n\tfor _, role := range roles {\n\t\tapiRoles = append(apiRoles, role.ToApi())\n\t}\n\n\tbytes, err := json.Marshal(apiRoles)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error marshalling response: %v\\n\", err)\n\t\thttp.Error(w, \"Error marshalling response: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tlog.Println(\"Successfully listed org roles\")\n","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/orgs.go#L219-L255","documentation":"db.ListOrgRoles(auth.OrgId) failed while querying org_roles for the org, so the handler returns HTTP 500 with the wrapped error. The org exists and the user has permission, but the roles query itself errored.","triggerScenarios":"Calling the list-org-roles endpoint when the org_roles table is missing or schema-mismatched, the DB connection drops mid-query, or rows contain data that fails to scan into the OrgRole model.","commonSituations":"Unapplied migrations leaving the org_roles table absent, malformed/corrupt role rows after manual edits, transient Postgres restarts, schema drift after upgrading the server.","solutions":["Read the underlying error from server logs (logged immediately before the 500)","Run pending database migrations to ensure org_roles schema is current","Verify DB connectivity and retry after transient outages","Check for scan errors caused by manually modified role rows"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// client: preflight DB-backed endpoints lightly; mostly ensure org membership first\nconst org = await getCurrentOrg();\nif (!org || org.isTrial) return; // trial orgs are rejected earlier\n","typeGuard":null,"tryCatchPattern":"try {\n  const roles = await listOrgRoles();\n} catch (e) {\n  if (e.status === 500) { await backoffRetry(e, { attempts: 3 }); } // transient DB errors\n  else throw e;\n}","preventionTips":["Apply DB migrations before serving traffic","Add bounded retry with backoff for 500s on read endpoints","Watch for scan/schema errors after server upgrades","Avoid manual edits to org_roles rows"],"tags":["database","http-500","org-roles"],"backgroundTag":"database-query-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}