{"record":{"id":"dc70ccac1aeef7ec","repo":"koala73/worldmonitor","slug":"invitee-domain-mismatch","errorCode":"INVITEE_DOMAIN_MISMATCH","errorMessage":"INVITEE_DOMAIN_MISMATCH","messagePattern":"INVITEE_DOMAIN_MISMATCH","errorType":"error_code","errorClass":"ConvexError","httpStatus":null,"severity":"error","filePath":"convex/payments/businessSeats.ts","lineNumber":187,"sourceCode":"\n    // Separate new invites from duplicates before the cap check so a duplicate\n    // re-invite is idempotent even when the cap is full.\n    const newEmails: string[] = [];\n    const results: Array<{\n      email: string;\n      grantId: string;\n      status: \"created\" | \"already_pending\" | \"already_accepted\";\n    }> = [];\n\n    for (const email of emails) {\n      if (email === normalizedOwnerEmail) {\n        throw new ConvexError({ kind: \"CANNOT_INVITE_SELF\" });\n      }\n      if (!isCorporateDomain(email)) {\n        throw new ConvexError({ kind: \"INVITEE_DOMAIN_NOT_CORPORATE\" });\n      }\n\n      const existing = existingByEmail.get(email);\n      if (existing) {\n        if (existing.status === \"accepted\") {\n          results.push({ email, grantId: existing._id, status: \"already_accepted\" });\n          continue;\n        }\n        if (existing.status === \"pending\" && existing.expiresAt > now) {\n          results.push({ email, grantId: existing._id, status: \"already_pending\" });\n          continue;\n        }\n      }\n      newEmails.push(email);\n    }\n\n    const currentCount = await countActiveOrPendingGrants(\n      ctx,\n      businessSub.dodoSubscriptionId,\n      now,\n    );","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/convex/payments/businessSeats.ts#L169-L205","documentation":"Generic sentinel thrown by the business-seat invite loop when an invitee email fails the corporate-domain check (isCorporateDomain). The invite is rejected before any seat is granted because the workspace only accepts addresses on the company domain; the input at fault is the individual `email` element currently being iterated, not the whole batch.","triggerScenarios":"Thrown at convex/payments/businessSeats.ts:188 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Filter or correct the offending email addresses client-side so every invitee is on the corporate domain before submitting the batch","Surface the offending email to the user so they know which invite entry to fix or remove","If the domain should be allowed, update the corporate-domain configuration used by isCorporateDomain and retry"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}