plandex-ai/plandex · error
Error validating org membership:
Error message
Error validating org membership:
What it means
InviteUserHandler wraps any error returned by db.ValidateOrgMembership(user.Id, auth.OrgId) into an HTTP 500 prefixed with 'Error validating org membership: '. This is thrown when the database lookup that checks whether an existing user is already a member of the org fails for infrastructure reasons (connection loss, bad query, context cancellation), not because the user is or isn't a member. It indicates a server-side data-layer failure during invite creation.
Source
Thrown at app/server/handlers/invites.go:102
log.Printf("User already has access to org via domain: %v\n", domain)
http.Error(w, "User already has access to org via domain: "+*domain, http.StatusBadRequest)
}
// ensure user with this email isn't already in the org
user, err := db.GetUserByEmail(req.Email)
if err != nil {
log.Printf("Error getting user: %v\n", err)
http.Error(w, "Error getting user: "+err.Error(), http.StatusInternalServerError)
return
}
if user != nil {
isMember, err := db.ValidateOrgMembership(user.Id, auth.OrgId)
if err != nil {
log.Printf("Error validating org membership: %v\n", err)
http.Error(w, "Error validating org membership: "+err.Error(), http.StatusInternalServerError)
return
}
if isMember {
log.Println("User is already a member of org")
http.Error(w, "User is already a member of org", http.StatusBadRequest)
return
}
}
// ensure invite isn't already active
invite, err := db.GetActiveInviteByEmail(auth.OrgId, req.Email)
if err != nil {
log.Printf("Error getting invite: %v\n", err)
http.Error(w, "Error getting invite: "+err.Error(), http.StatusInternalServerError)
return
}View on GitHub (pinned to e2d772072e)
Solutions
- Check server logs for the same message to see the wrapped underlying DB error and fix that root cause first
- Verify database connectivity (DATABASE_URL, network, Postgres uptime) and connection pool sizing
- Confirm schema migrations have run so users/org membership tables exist with expected columns
- Retry the invite request after the transient DB issue resolves
- If it persists, add retry/backoff or better error wrapping around ValidateOrgMembership
Example fix
// before
if err != nil {
http.Error(w, "Error validating org membership: "+err.Error(), http.StatusInternalServerError)
return
}
// after
if err != nil {
log.Printf("Error validating org membership: %v\n", err)
writeApiError(w, shared.ApiError{Type: shared.ApiErrorTypeOther, Status: http.StatusInternalServerError, Msg: "Failed to check org membership, please try again"})
return
} Defensive patterns
Strategy: retry
Validate before calling
// client: only call invite when you believe the email is new; nothing to pre-validate server-side,
// but you can pre-check membership via the org members list before inviting
if org.Members != nil {
for _, m := range org.Members {
if strings.ToLower(m.Email) == strings.ToLower(email) {
return fmt.Errorf("%s is already a member", email)
}
}
} Type guard
func isMembershipValidationError(resp *http.Response, body string) bool {
return resp != nil && resp.StatusCode == http.StatusInternalServerError && strings.Contains(body, "Error validating org membership")
} Try / catch
resp, err := client.Post(inviteUrl, jsonBody)
if err != nil { return err }
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode == 500 && strings.Contains(string(body), "Error validating org membership") {
return fmt.Errorf("transient server error checking membership; safe to retry: %s", body)
} Prevention
- Pre-check the org members list before sending an invite
- Treat 500s on this endpoint as retryable after backoff
- Monitor DB health/alerts so connectivity issues are caught early
- Keep migrations in sync with deployed server code
When it happens
Trigger: POST to the invite-user endpoint with an email that resolves to an existing user (db.GetUserByEmail returns non-nil) while the ValidateOrgMembership query fails: DB is down/restarting, connection pool exhausted, query timeout, request context canceled, or the org_membership/users table is missing or corrupted.
Common situations: Deployments where Postgres is under-provisioned or the connection pool is too small under load; transient network blips between the server and database; running migrations partially so org membership tables are missing; long-running requests canceled by client timeouts mid-handler.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Error getting invite:
- Error listing invites:
- error getting current plan state params: %v
- error getting contexts: %v
- error validating project
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/4f1035fec47e162c.
Report an issue: GitHub.