different-ai/openwork · error · OrganizationEmailDomainRestrictionError

${allowedEmailDomains.length === 1 ? `This workspace only al

Error message

${allowedEmailDomains.length === 1 ? `This workspace only allows ${allowedEmailDomains[0]} email addresses.` : `This workspace only allows email addresses from these domains: ${allowedEmailDomains.join(", ")}.`}

What it means

This error is raised by OrganizationEmailDomainRestrictionError when a user tries to accept a workspace invitation whose organization restricts membership to specific email domains, and the invitee's email domain is not in the organization's allowedEmailDomains list. The message dynamically lists the single allowed domain or all allowed domains.

Source

Thrown at ee/apps/den-api/src/orgs.ts:957

        return {
          status: "membership_removed",
          invitation,
        }
      }
    }

    return null
  }

  const organizationRows = await db
    .select({ allowedEmailDomains: OrganizationTable.allowedEmailDomains })
    .from(OrganizationTable)
    .where(eq(OrganizationTable.id, invitation.organizationId))
    .limit(1)

  const allowedEmailDomains = normalizeStoredAllowedEmailDomains(organizationRows[0]?.allowedEmailDomains)
  if (!isEmailAllowedForOrganization(allowedEmailDomains, input.email)) {
    throw new OrganizationEmailDomainRestrictionError(input.email, allowedEmailDomains ?? [])
  }

  const accepted = await acceptInvitation(invitation, input.userId)
  if (!accepted) {
    const currentInvitation = await getInvitationById(input.invitationId)
    if (currentInvitation && getInvitationStatus(currentInvitation) === "accepted") {
      const removedMember = await findSoftRemovedMemberForUser({
        organizationId: currentInvitation.organizationId,
        userId: input.userId,
      })
      if (removedMember) {
        return {
          status: "membership_removed",
          invitation: currentInvitation,
        }
      }
    }
    return null

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Use the email address on a domain listed in the organization's allowedEmailDomains to accept the invitation.
  2. Ask the workspace admin to add the invitee's email domain to the organization's allowedEmailDomains settings, then retry.
  3. Re-issue the invitation to the correct email address if the original was wrong.
  4. Verify normalizeStoredAllowedEmailDomains parsing matches how the admin entered the domains (e.g. leading @, casing).

Example fix

// before
await acceptOrgInvitation({ invitationId, userId, email: "dev@gmail.com" })
// after
await acceptOrgInvitation({ invitationId, userId, email: "dev@acme.com" }) // domain allowed by the org
Defensive patterns

Strategy: validation

Validate before calling

const allowed = normalizeStoredAllowedEmailDomains(org.allowedEmailDomains)
if (!isEmailAllowedForOrganization(allowed, userEmail)) {
  throw new Error(`Email ${userEmail} not allowed; permitted domains: ${(allowed ?? []).join(", ")}`)
}

Type guard

function emailAllowedFor(email: string, domains: string[] | null): boolean {
  const suffixes = (domains ?? []).map(d => d.startsWith("@") ? d.toLowerCase() : `@${d.toLowerCase()}`)
  return suffixes.some(s => email.toLowerCase().endsWith(s))
}

Try / catch

try {
  await acceptInvitation({ invitationId, userId, email })
} catch (e) {
  if (e instanceof OrganizationEmailDomainRestrictionError) {
    return { ok: false, reason: "domain-restricted", allowedDomains: e.allowedEmailDomains }
  }
  throw e
}

Prevention

When it happens

Trigger: Calling the accept-invitation flow (acceptInvitation handler in orgs.ts) where isEmailAllowedForOrganization(normalizeStoredAllowedEmailDomains(org.allowedEmailDomains), input.email) returns false — e.g. accepting with a personal gmail.com address when the org only allows @acme.com.

Common situations: User accepts an invite with a different email than the one the admin intended; admin changed allowedEmailDomains after sending the invite; the allowed-domains list is stored in a legacy/normalized format that fails to match; invite forwarded to a colleague with another domain.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/496265afd6eef298. Report an issue: GitHub.