{"record":{"id":"d67d5aa00afff364","repo":"medusajs/medusa","slug":"unauthorized-d67d5a","errorCode":"UNAUTHORIZED","errorMessage":"Only ${authProvider} identities can create a user account for this authentication context","messagePattern":"Only (.+?) identities can create a user account for this authentication context","errorType":"exception","errorClass":"MedusaError","httpStatus":401,"severity":"error","filePath":"packages/medusa/src/api/auth/[auth_provider]/user/route.ts","lineNumber":52,"sourceCode":"      \"Email is required to create a user account.\"\n    )\n  }\n\n  // Check that the auth identity was created by the provider named in the route.\n  const providerIdentities = await query\n    .graph({\n      entity: \"auth_identity\",\n      fields: [\"id\", \"provider_identities.provider\"],\n      filters: {\n        id: req.auth_context.auth_identity_id,\n      },\n    })\n    .then((result) => result.data[0]?.provider_identities)\n  if (\n    providerIdentities?.length !== 1 ||\n    providerIdentities[0].provider !== authProvider\n  ) {\n    throw new MedusaError(\n      MedusaError.Types.UNAUTHORIZED,\n      `Only ${authProvider} identities can create a user account for this authentication context`\n    )\n  }\n\n  // Check if a user already exists for the identity-provider-verified email.\n  const user = await query\n    .graph({\n      entity: \"user\",\n      fields: [\"id\"],\n      filters: {\n        email: req.auth_context.user_metadata.email,\n      },\n    })\n    .then((result) => result.data[0])\n\n  // Link path: an existing user with a matching email is linked.\n  if (user) {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/medusa/src/api/auth/[auth_provider]/user/route.ts#L34-L70","documentation":"Thrown when the auth identity resolved from the token does not have exactly one provider identity, or that provider identity's provider does not match the :auth_provider in the URL. The route only allows creating a user through the same provider that authenticated the request. Maps to HTTP 401 (UNAUTHORIZED).","triggerScenarios":"Calling POST /auth/google/user with a token minted via emailpass; an identity that has zero or multiple provider identities (e.g. identity linked to two providers).","commonSituations":"Mismatch between URL provider segment and the provider actually used to authenticate; identities progressively linked to multiple providers; copy-pasted route from another provider's flow.","solutions":["Use the same provider in the URL as the one used to obtain the JWT","Inspect the auth identity's provider_identities (query auth provider identity) to confirm exactly one exists","Unlink extra provider identities if multiple are attached","Re-authenticate with the intended provider to mint a matching token"],"exampleFix":"// before\nconst token = await sdk.auth.authenticate('emailpass', {...})\nawait fetch('/auth/google/user', { headers: { Authorization: `Bearer ${token}` }, method: 'POST' })\n\n// after\nawait fetch('/auth/emailpass/user', { headers: { Authorization: `Bearer ${token}` }, method: 'POST' })","handlingStrategy":"validation","validationCode":"const claims = parseJwt(token)\nconst urlProvider = providerUsedToAuthenticate // track alongside token\nif (claims.auth_provider !== urlProvider) throw new Error('provider mismatch')","typeGuard":null,"tryCatchPattern":"catch (e) { if (e.type === 'unauthorized' && /identities can create/.test(e.message)) retryWithCorrectProvider() else throw e }","preventionTips":["Derive the URL provider segment from the auth flow, never hard-code it","Store which provider minted the token alongside it","Keep identities single-provider during signup flows"],"tags":["auth","provider-mismatch","unauthorized"],"backgroundTag":"auth-provider-mismatch","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}