Found while driving the organizations.* routes for #14314 (card 3 of the #12104 family). Out of that card's ruled scope (listMine is already typed and the defect is a runtime refusal), so recorded here. No assignee, no label — left for triage.
What plugin-auth declares
packages/plugins/plugin-auth/src/auth-manager.ts, the organization({ ... }) options:
Without a mailer wired in framework, requiring email verification before accepting invitations dead-ends every invite flow with FORBIDDEN EMAIL_VERIFICATION_REQUIRED…. Default-off here keeps the built-in /accept-invitation route usable for pilots
so requireEmailVerificationOnInvitation: false is set, and the SDK's organizations.invitations.listMine JSDoc says it is "Used by the per-user Invitations inbox page."
What the vendor does
better-auth 1.7.2, plugins/organization/routes/crud-invites.mjs, listUserInvitations: if (session && !session.user.emailVerified) throw APIError.from('FORBIDDEN', EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION) — unconditional, it does not read requireEmailVerificationOnInvitation (the accept / reject / get-invitation routes DO read it, via shouldRequireVerifiedEmailForInvitationIdAction).
Measured
Real AuthManager (better-auth 1.7.2, organization plugin) over a real SqlDriver (better-sqlite3), no mailer:
- owner signs up, creates an organization, invites
b@example.com
b@example.com signs up through the invitation carve-out (email stays unverified — there is no mailer to verify it)
GET /organization/list-user-invitations as B -> 403 {"message":"Email verification required to view or list invitations for the session email","code":"EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION"}
POST /organization/accept-invitation as B with the same invitation id -> 200 (the option is honoured here)
The same 403 came back through the real ObjectStackClient (client.organizations.invitations.listMine() rejected with that message). So on the deployment shape the option exists for, the invitee can ACCEPT an invitation whose id they were handed but can never LIST it — the inbox page the SDK method serves is empty-by-403 for every user until a mailer verifies them.
Class
Reproducible defect on a declared capability (the inbox is advertised for pilots without a mailer; the route refuses them). Fix shape is a triage question: an ObjectStack before-hook on /organization/list-user-invitations that answers the listing itself when requireEmailVerificationOnInvitation is false, an upstream report to better-auth, or documenting the inbox as verified-users-only.
Refs: #14314 (where it was measured), #12104 (family head).
Generated by Claude Code
Found while driving the
organizations.*routes for #14314 (card 3 of the #12104 family). Out of that card's ruled scope (listMineis already typed and the defect is a runtime refusal), so recorded here. No assignee, no label — left for triage.What plugin-auth declares
packages/plugins/plugin-auth/src/auth-manager.ts, theorganization({ ... })options:so
requireEmailVerificationOnInvitation: falseis set, and the SDK'sorganizations.invitations.listMineJSDoc says it is "Used by the per-user Invitations inbox page."What the vendor does
better-auth 1.7.2,
plugins/organization/routes/crud-invites.mjs,listUserInvitations:if (session && !session.user.emailVerified) throw APIError.from('FORBIDDEN', EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION)— unconditional, it does not readrequireEmailVerificationOnInvitation(theaccept/reject/get-invitationroutes DO read it, viashouldRequireVerifiedEmailForInvitationIdAction).Measured
Real
AuthManager(better-auth 1.7.2, organization plugin) over a realSqlDriver(better-sqlite3), no mailer:b@example.comb@example.comsigns up through the invitation carve-out (email stays unverified — there is no mailer to verify it)GET /organization/list-user-invitationsas B ->403 {"message":"Email verification required to view or list invitations for the session email","code":"EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION"}POST /organization/accept-invitationas B with the same invitation id ->200(the option is honoured here)The same 403 came back through the real
ObjectStackClient(client.organizations.invitations.listMine()rejected with that message). So on the deployment shape the option exists for, the invitee can ACCEPT an invitation whose id they were handed but can never LIST it — the inbox page the SDK method serves is empty-by-403 for every user until a mailer verifies them.Class
Reproducible defect on a declared capability (the inbox is advertised for pilots without a mailer; the route refuses them). Fix shape is a triage question: an ObjectStack before-hook on
/organization/list-user-invitationsthat answers the listing itself whenrequireEmailVerificationOnInvitationisfalse, an upstream report to better-auth, or documenting the inbox as verified-users-only.Refs: #14314 (where it was measured), #12104 (family head).
Generated by Claude Code