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

  1. Check server logs for the same message to see the wrapped underlying DB error and fix that root cause first
  2. Verify database connectivity (DATABASE_URL, network, Postgres uptime) and connection pool sizing
  3. Confirm schema migrations have run so users/org membership tables exist with expected columns
  4. Retry the invite request after the transient DB issue resolves
  5. 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

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


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/4f1035fec47e162c. Report an issue: GitHub.