{"record":{"id":"7c3bc5679d41cc13","repo":"koala73/worldmonitor","slug":"cannot-invite-self","errorCode":"CANNOT_INVITE_SELF","errorMessage":"CANNOT_INVITE_SELF","messagePattern":"CANNOT_INVITE_SELF","errorType":"error_code","errorClass":"ConvexError","httpStatus":null,"severity":"error","filePath":"convex/payments/businessSeats.ts","lineNumber":181,"sourceCode":"        q.eq(\"businessSubscriptionId\", businessSub.dodoSubscriptionId),\n      )\n      .collect();\n    const existingByEmail = new Map(\n      existingGrants.map((g) => [g.inviteeEmail, g]),\n    );\n\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    }","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/convex/payments/businessSeats.ts#L163-L199","documentation":"Structured ConvexError thrown by inviteSeats when one of the submitted emails equals the owner's own normalized email. Owners already hold the Business entitlement; inviting yourself is rejected while iterating the invitee list.","triggerScenarios":"Thrown at convex/payments/businessSeats.ts:182 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove the owner's own address from the invite list","Filter the signed-in user's email out of the batch in the invite UI"],"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"}