{"record":{"id":"752d36aa9c022c1c","repo":"plandex-ai/plandex","slug":"error-getting-org-err-error","errorCode":null,"errorMessage":"Error getting org: {err.Error()}","messagePattern":"Error getting org: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/users.go","lineNumber":38,"sourceCode":"\n\tif os.Getenv(\"GOENV\") == \"development\" && os.Getenv(\"LOCAL_MODE\") == \"1\" {\n\t\twriteApiError(w, shared.ApiError{\n\t\t\tType:   shared.ApiErrorTypeOther,\n\t\t\tStatus: http.StatusForbidden,\n\t\t\tMsg:    \"Local mode is not supported for user management\",\n\t\t})\n\t\treturn\n\t}\n\n\tauth := Authenticate(w, r, true)\n\tif auth == nil {\n\t\treturn\n\t}\n\n\torg, err := db.GetOrg(auth.OrgId)\n\tif err != nil {\n\t\tlog.Printf(\"Error getting org: %v\\n\", err)\n\t\thttp.Error(w, \"Error getting org: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tif org.IsTrial {\n\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 users\",\n\t\t})\n\t\treturn\n\t}\n\n\tusers, err := db.ListUsers(auth.OrgId)\n\tif err != nil {\n\t\tlog.Println(\"Error listing users: \", err)\n\t\thttp.Error(w, \"Error listing users: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/users.go#L20-L56","documentation":"ListUsersHandler loads the org record with db.GetOrg(auth.OrgId) before checking trial status. Any DB error (unreachable database, missing org row, scan/schema mismatch) is returned as 500 with the raw error text appended: 'Error getting org: <err>'. Unlike the settings handlers, this leaks the underlying error string to the client.","triggerScenarios":"GET the users list endpoint when the orgs lookup fails: DB down, org row deleted while the auth session still references its ID, column mismatch after a migration, or connection pool exhaustion.","commonSituations":"Server pointed at the wrong DATABASE_URL after a config change; org deleted during cleanup while tokens remain valid; schema drift from an unapplied migration.","solutions":["Read the response/server log — this error includes the raw DB error text","Verify DATABASE_URL points at the correct, healthy database","Confirm the org ID from the auth token exists in the orgs table","Apply pending migrations so the orgs schema matches the code","Retry once the DB is reachable"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const res = await fetch(`${base}/org/users`, { headers: authHeaders });\nif (res.status === 500 && /Error getting org/.test(await res.text())) {\n  await checkDbHealthOrRetry();\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await api.listUsers();\n} catch (e) {\n  if (e.status >= 500) await backoffRetry(() => api.listUsers(), 3);\n  else if (e.status === 403 && e.type === 'trial_action_not_allowed') upgradeOrg();\n  else throw e;\n}","preventionTips":["Retry 5xx list endpoints with exponential backoff","Confirm org still exists when reusing long-lived tokens","Keep DATABASE_URL and migrations consistent across deploys","Monitor DB availability with health checks"],"tags":["database","http-500","org"],"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-12T22:17:10.623Z"}