{"record":{"id":"68668cfa93fcda74","repo":"plandex-ai/plandex","slug":"error-listing-invites","errorCode":null,"errorMessage":"Error listing invites: ","messagePattern":"Error listing invites: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/invites.go","lineNumber":199,"sourceCode":"\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 invites\",\n\t\t})\n\t\treturn\n\t}\n\n\tinvites, err := db.ListPendingInvites(auth.OrgId)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error listing invites: %v\\n\", err)\n\t\thttp.Error(w, \"Error listing invites: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tvar apiInvites []*shared.Invite\n\tfor _, invite := range invites {\n\t\tapiInvites = append(apiInvites, invite.ToApi())\n\t}\n\n\tbytes, err := json.Marshal(apiInvites)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error marshalling invites: %v\\n\", err)\n\t\thttp.Error(w, \"Error marshalling invites: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.Write(bytes)\n\tlog.Println(\"Successfully processed request for ListPendingInvitesHandler\")","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/invites.go#L181-L217","documentation":"ListPendingInvitesHandler wraps any error from db.ListPendingInvites(auth.OrgId) into an HTTP 500 prefixed with 'Error listing invites: '. This is the core SELECT of pending invites for the org; the error indicates the query failed rather than an empty result (an empty list would marshal fine). Server-side data-layer failure.","triggerScenarios":"GET to the pending-invites endpoint where the ListPendingInvites query fails: Postgres down, pool exhaustion, query timeout, invites table missing or columns changed after migration, row scan/type mismatch, or canceled request context.","commonSituations":"Partially applied migrations altering the invites schema; database overload returning timeouts; connection leaks under load; deploying new code against an old schema (or vice versa).","solutions":["Read the server log for the wrapped underlying DB error","Verify the invites table schema matches what ListPendingInvites expects","Check DB health, pool sizing, and query timeouts","Retry after resolving; add pagination/limit if the invites result set is huge"],"exampleFix":"// before\nif err != nil {\n    http.Error(w, \"Error listing invites: \"+err.Error(), http.StatusInternalServerError)\n    return\n}\n// after\nif err != nil {\n    log.Printf(\"Error listing invites: %v\\n\", err)\n    writeApiError(w, shared.ApiError{Type: shared.ApiErrorTypeOther, Status: http.StatusInternalServerError, Msg: \"Failed to list invites, please try again\"})\n    return\n}","handlingStrategy":"retry","validationCode":"// no client-side pre-check possible; server-side verify schema before deploy:\n// psql -c \"\\\\d invites\" must match the columns ListPendingInvites selects","typeGuard":"func isListInvitesServerError(statusCode int, body string) bool {\n    return statusCode == http.StatusInternalServerError && strings.Contains(body, \"Error listing invites\")\n}","tryCatchPattern":"resp, err := client.Get(pendingInvitesUrl)\nbody, _ := io.ReadAll(resp.Body)\nif resp.StatusCode == 500 && strings.Contains(string(body), \"Error listing invites\") {\n    return fmt.Errorf(\"transient DB error listing invites; retry with backoff: %s\", body)\n}","preventionTips":["Run and verify migrations (invites table/columns) before each deploy","Monitor DB pool saturation and query timeouts","Set sane statement timeouts and retry transient failures","An empty list is a normal 200 — only 500 means the query itself failed"],"tags":["database","http-500","invites","go"],"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"}