koala73/worldmonitor · error · ConvexError
CANNOT_INVITE_SELF
CANNOT_INVITE_SELF
Error message
CANNOT_INVITE_SELF
What it means
Thrown by `inviteSeats` during the per-email loop when an invitee address equals the owner's own (normalized) email. Owners cannot invite themselves as a seat. Object-typed ConvexError (`{ kind: "CANNOT_INVITE_SELF" }`).
Source
Thrown at convex/payments/businessSeats.ts:182
q.eq("businessSubscriptionId", businessSub.dodoSubscriptionId),
)
.collect();
const existingByEmail = new Map(
existingGrants.map((g) => [g.inviteeEmail, g]),
);
// Separate new invites from duplicates before the cap check so a duplicate
// re-invite is idempotent even when the cap is full.
const newEmails: string[] = [];
const results: Array<{
email: string;
grantId: string;
status: "created" | "already_pending" | "already_accepted";
}> = [];
for (const email of emails) {
if (email === normalizedOwnerEmail) {
throw new ConvexError({ kind: "CANNOT_INVITE_SELF" });
}
if (!isCorporateDomain(email)) {
throw new ConvexError({ kind: "INVITEE_DOMAIN_NOT_CORPORATE" });
}
if (!sameDomain(ownerEmail, email)) {
throw new ConvexError({ kind: "INVITEE_DOMAIN_MISMATCH" });
}
const existing = existingByEmail.get(email);
if (existing) {
if (existing.status === "accepted") {
results.push({ email, grantId: existing._id, status: "already_accepted" });
continue;
}
if (existing.status === "pending" && existing.expiresAt > now) {
results.push({ email, grantId: existing._id, status: "already_pending" });
continue;
}View on GitHub (pinned to ffec79ac33)
Solutions
- Remove the owner's own email from the invite list before submitting.
- Client-side, filter out the current user's email from the recipients.
- Warn if the owner's address is detected in the input.
Example fix
// before
await inviteSeats({ emails: ["owner@acme.com", "a@acme.com"] });
// after
const emails = recipients.filter(e => e !== currentUserEmail);
await inviteSeats({ emails }); Defensive patterns
Strategy: validation
Validate before calling
const emails = rawEmails.filter(e => e.trim().toLowerCase() !== ownerEmail.toLowerCase());
if (emails.length === 0) { showToast("You can't invite yourself."); return; }
await inviteSeats({ emails }); Prevention
- Strip the current user's email from the recipient list client-side.
- Warn when the owner's address appears in the input.
When it happens
Trigger: The owner's email appears in the `emails` array passed to `inviteSeats` (e.g. `inviteSeats({ emails: ["owner@acme.com"] })` where owner@acme.com is the caller).
Common situations: Owner pasted their own address by mistake; an autocomplete defaulted to the signed-in user; 'invite all' from a contact list that included the owner.
Related errors
- OWNER_EMAIL_UNAVAILABLE
- OWNER_NOT_BUSINESS
- OWNER_DOMAIN_NOT_CORPORATE
- NO_EMAILS_PROVIDED
- TOO_MANY_EMAILS
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/7c3bc5679d41cc13.
Report an issue: GitHub.