{"record":{"id":"5b69ed6d6e0b2ab5","repo":"medusajs/medusa","slug":"customer-with-this-email-already-has-an-account","errorCode":null,"errorMessage":"Customer with this email already has an account","messagePattern":"Customer with this email already has an account","errorType":"exception","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/core/core-flows/src/customer/steps/validate-customer-account-creation.ts","lineNumber":49,"sourceCode":"    const { email } = input.customerData\n\n    if (!email) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"Email is required to create a customer\"\n      )\n    }\n\n    // Check if customer with email already exists\n    const existingCustomers = await customerService.listCustomers({ email })\n\n    if (existingCustomers?.length) {\n      const hasExistingAccount = existingCustomers.some(\n        (customer) => customer.has_account\n      )\n\n      if (hasExistingAccount && input.authIdentityId) {\n        throw new MedusaError(\n          MedusaError.Types.DUPLICATE_ERROR,\n          \"Customer with this email already has an account\"\n        )\n      }\n\n      if (!hasExistingAccount && !input.authIdentityId) {\n        throw new MedusaError(\n          MedusaError.Types.DUPLICATE_ERROR,\n          \"Guest customer with this email already exists\"\n        )\n      }\n    }\n  }\n)\n","sourceCodeStart":31,"sourceCodeEnd":64,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/core-flows/src/customer/steps/validate-customer-account-creation.ts#L31-L64","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nawait createCustomerAccountWorkflow(container).run({\n  input: { customerData: { email }, authIdentityId },\n})\n\n// after: pre-check and direct to login/link\nconst [existing] = await customerService.listCustomers({ email })\nif (existing?.has_account) {\n  throw new MedusaError(MedusaError.Types.DUPLICATE_ERROR, \"Please log in\")\n}\nawait createCustomerAccountWorkflow(container).run({ input: { customerData: { email }, authIdentityId } })","handlingStrategy":"validation","validationCode":"const [existing] = await customerService.listCustomers({ email })\nif (existing?.has_account) return { alreadyRegistered: true }","typeGuard":null,"tryCatchPattern":"try { await createCustomerAccountWorkflow(scope).run({ input }) } catch (e) { if (e.type === MedusaError.Types.DUPLICATE_ERROR) { /* prompt login / send to auth identity linking */ } throw e }","preventionTips":["Pre-check email registration before invoking account creation","Catch DUPLICATE_ERROR and offer a login/link flow instead of raw failure"],"tags":["customer","duplicate","signup","auth"],"backgroundTag":"duplicate-account-email","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}