medusajs/medusa · error · MedusaError
Customer with this email already has an account
Error message
Customer with this email already has an account
What it means
Thrown when creating a customer account for an email that already belongs to a registered customer (has_account=true) and an authIdentityId is supplied — i.e. trying to attach a new auth identity to an already-registered email.
Source
Thrown at packages/core/core-flows/src/customer/steps/validate-customer-account-creation.ts:49
const { email } = input.customerData
if (!email) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Email is required to create a customer"
)
}
// Check if customer with email already exists
const existingCustomers = await customerService.listCustomers({ email })
if (existingCustomers?.length) {
const hasExistingAccount = existingCustomers.some(
(customer) => customer.has_account
)
if (hasExistingAccount && input.authIdentityId) {
throw new MedusaError(
MedusaError.Types.DUPLICATE_ERROR,
"Customer with this email already has an account"
)
}
if (!hasExistingAccount && !input.authIdentityId) {
throw new MedusaError(
MedusaError.Types.DUPLICATE_ERROR,
"Guest customer with this email already exists"
)
}
}
}
)
View on GitHub (pinned to 5e06e544a2)
Solutions
- Instead of creating, authenticate the existing customer and use the auth identity merge/link flow (e.g. linkAuthIdentity / existing account login)
- Surface 'email already registered' to the client and prompt login
- Guard by checking the customer by email before invoking the workflow
Example fix
// before
await createCustomerAccountWorkflow(container).run({
input: { customerData: { email }, authIdentityId },
})
// after: pre-check and direct to login/link
const [existing] = await customerService.listCustomers({ email })
if (existing?.has_account) {
throw new MedusaError(MedusaError.Types.DUPLICATE_ERROR, "Please log in")
}
await createCustomerAccountWorkflow(container).run({ input: { customerData: { email }, authIdentityId } }) Defensive patterns
Strategy: validation
Validate before calling
const [existing] = await customerService.listCustomers({ email })
if (existing?.has_account) return { alreadyRegistered: true } Try / catch
try { await createCustomerAccountWorkflow(scope).run({ input }) } catch (e) { if (e.type === MedusaError.Types.DUPLICATE_ERROR) { /* prompt login / send to auth identity linking */ } throw e } Prevention
- Pre-check email registration before invoking account creation
- Catch DUPLICATE_ERROR and offer a login/link flow instead of raw failure
When it happens
Trigger: Calling createCustomerAccountWorkflow where the email already has has_account=true and input.authIdentityId is set (e.g. user registers a second auth provider on an email that is already registered).
Common situations: User signs up again with a different auth provider (Google vs email/password) using the same email; double-submit of the registration form; invitation/accept flows that call account creation for an existing account.
Related errors
- Guest customer with this email already exists
- Email is required to create a customer
- Invalid step input
- Invalid step input
- Auth identity not found
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/5b69ed6d6e0b2ab5.
Report an issue: GitHub.