{"record":{"id":"fe2ce99445e7f076","repo":"koala73/worldmonitor","slug":"invalid-invite-token","errorCode":"INVALID_INVITE_TOKEN","errorMessage":"INVALID_INVITE_TOKEN","messagePattern":"INVALID_INVITE_TOKEN","errorType":"error_code","errorClass":"ConvexError","httpStatus":null,"severity":"error","filePath":"convex/payments/businessSeats.ts","lineNumber":471,"sourceCode":"    const identity = await resolveUserIdentity(ctx);\n    const inviteeEmail = identity?.email?.trim().toLowerCase();\n    if (!inviteeEmail) {\n      throw new ConvexError({ kind: \"INVITEE_EMAIL_UNAVAILABLE\" });\n    }\n\n    const grant = await ctx.db.get(args.grantId);\n    if (!grant) {\n      throw new ConvexError({ kind: \"GRANT_NOT_FOUND\" });\n    }\n    if (grant.status !== \"pending\") {\n      throw new ConvexError({ kind: \"INVITE_ALREADY_USED\" });\n    }\n    const now = Date.now();\n    if (grant.expiresAt <= now) {\n      throw new ConvexError({ kind: \"INVITE_EXPIRED\" });\n    }\n    if (!(await verifyBusinessInviteToken(args.grantId, args.token))) {\n      throw new ConvexError({ kind: \"INVALID_INVITE_TOKEN\" });\n    }\n    if (grant.inviteeEmail !== inviteeEmail) {\n      throw new ConvexError({ kind: \"INVITE_EMAIL_MISMATCH\" });\n    }\n    if (!sameDomain(grant.inviteeEmail, inviteeEmail)) {\n      throw new ConvexError({ kind: \"INVITE_EMAIL_MISMATCH\" });\n    }\n    if (!isCorporateDomain(inviteeEmail)) {\n      throw new ConvexError({ kind: \"INVITEE_DOMAIN_NOT_CORPORATE\" });\n    }\n\n    const businessSub = await ctx.db\n      .query(\"subscriptions\")\n      .withIndex(\"by_dodoSubscriptionId\", (q) =>\n        q.eq(\"dodoSubscriptionId\", grant.businessSubscriptionId),\n      )\n      .unique();\n    if (!businessSub || !isBusinessPlan(businessSub.planKey) || !isCoveringAt(businessSub, now)) {","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/convex/payments/businessSeats.ts#L453-L489","documentation":"Structured ConvexError thrown by acceptBusinessInvite when the supplied HMAC invite token fails verification against the grant. Tokens are single-use, server-signed secrets; a forged, truncated, or token/grant mismatch fails this guard before any entitlement is granted.","triggerScenarios":"Thrown at convex/payments/businessSeats.ts:475 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Use the exact token from the invite email link, unmodified and complete","Do not attempt to reuse a token accepted in another session or for another grant","Request a new invite if the token may have been regenerated"],"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"}