{"record":{"id":"3590befce3f0c0c1","repo":"plandex-ai/plandex","slug":"error-deleting-invite","errorCode":null,"errorMessage":"Error deleting invite: ","messagePattern":"Error deleting invite: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/invites.go","lineNumber":402,"sourceCode":"\t}\n\n\t// ensure current user can remove target invite\n\tremovePermission := shared.Permission(strings.Join([]string{string(shared.PermissionRemoveUser), invite.OrgRoleId}, \"|\"))\n\n\tinvitePermission := shared.Permission(strings.Join([]string{string(shared.PermissionInviteUser), invite.OrgRoleId}, \"|\"))\n\n\tif !(auth.HasPermission(removePermission) ||\n\t\t(auth.User.Id == invite.InviterId && auth.HasPermission(invitePermission))) {\n\t\tlog.Printf(\"User does not have permission to remove invite with role: %v\\n\", invite.OrgRoleId)\n\t\thttp.Error(w, \"User does not have permission to remove invite with role: \"+invite.OrgRoleId, http.StatusForbidden)\n\t\treturn\n\t}\n\n\terr = db.DeleteInvite(inviteId, nil)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error deleting invite: %v\\n\", err)\n\t\thttp.Error(w, \"Error deleting invite: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tlog.Println(\"Successfully deleted invite\")\n}\n","sourceCodeStart":384,"sourceCodeEnd":408,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/invites.go#L384-L408","documentation":"DeleteInviteHandler calls db.DeleteInvite(inviteId, nil) after authorization; if that mutation fails it responds 500 'Error deleting invite: <err>'. The permission checks already passed, so this is purely a persistence-layer failure (the nil transaction argument means it runs outside an explicit transaction).","triggerScenarios":"DELETE /invites/{inviteId} when the DELETE statement fails: DB connection dropped, deadlock/lock timeout on the invites row, constraint violation, or the row disappeared concurrently between the GetInvite read and the delete.","commonSituations":"Database failover mid-request; concurrent deletion by another admin (row already gone, depending on driver error semantics); long-running transaction holding a lock on the invites table.","solutions":["Check the server log for the exact DB error after 'Error deleting invite:'","Retry the delete; if the invite was concurrently removed, the 404 path will tell you","Verify DB health (locks, connectivity) and application user write privileges on invites"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if resp.StatusCode >= 500 {\n\tawait sleep(backoff)\n\t// retry delete; a subsequent 404 means it was concurrently removed\n}","typeGuard":null,"tryCatchPattern":"try {\n\tawait client.deleteInvite(inviteId)\n} catch (e) {\n\tif (e.status >= 500) { await retryWithBackoff(() => client.deleteInvite(inviteId)); return }\n\tthrow e\n}","preventionTips":["Make deletes idempotent: treat 404 after a 500 retry as success","Keep DB lock timeouts reasonable; avoid long transactions on invites","Monitor DB write errors and failover events"],"tags":["go","database","http-500"],"backgroundTag":"database-write-failure","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"}