{"record":{"id":"09d197f5eecabd0a","repo":"medusajs/medusa","slug":"mfa-challenge-does-not-support-method-method","errorCode":null,"errorMessage":"MFA challenge does not support method \"${method}\"","messagePattern":"MFA challenge does not support method \"(.+?)\"","errorType":"exception","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/modules/auth/src/services/auth-module.ts","lineNumber":848,"sourceCode":"      )\n    }\n\n    if (new Date(challenge.expires_at).getTime() <= Date.now()) {\n      throw new MedusaError(\n        MedusaError.Types.NOT_ALLOWED,\n        \"MFA challenge has expired\"\n      )\n    }\n\n    if (challenge.attempts >= challenge.max_attempts) {\n      throw new MedusaError(\n        MedusaError.Types.NOT_ALLOWED,\n        \"MFA challenge has too many failed attempts\"\n      )\n    }\n\n    if (!challenge.methods.includes(method)) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `MFA challenge does not support method \"${method}\"`\n      )\n    }\n  }\n\n  @InjectManager()\n  async createPasswordResetToken(\n    data: AuthTypes.CreatePasswordResetTokenDTO,\n    @MedusaContext() sharedContext: Context = {}\n  ): Promise<AuthTypes.CreatePasswordResetTokenResponse> {\n    return await this.createPasswordResetToken_(data, sharedContext)\n  }\n\n  @InjectTransactionManager()\n  protected async createPasswordResetToken_(\n    data: AuthTypes.CreatePasswordResetTokenDTO,\n    @MedusaContext() sharedContext: Context = {}","sourceCodeStart":830,"sourceCodeEnd":866,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/auth/src/services/auth-module.ts#L830-L866","documentation":"Raised when verifying an MFA challenge with a method that is not in the challenge's allowed methods list (e.g. the challenge was created for 'totp' but verification uses 'recovery_code'). INVALID_DATA — the request mismatches the challenge configuration.","triggerScenarios":"Passing method: 'recovery_code' to a challenge created only for 'otp'/'totp'; frontend hardcoding the wrong method name; copy-paste between flows using different methods.","commonSituations":"Multi-method MFA UIs where the user switches entry mode but the challenge is method-scoped; method string typos or casing differences.","solutions":["Send verification with the same method(s) the challenge was created with","Create a separate challenge for recovery-code verification if the flow needs it","Inspect the challenge DTO's methods array before choosing what to submit"],"exampleFix":"// before\nawait authModule.verifyAuthMfaChallenge({ challenge_id, method: 'recovery_code', body })\n// after\nconst challenge = await authModule.retrieveAuthMfaChallenge(challenge_id)\nawait authModule.verifyAuthMfaChallenge({ challenge_id, method: challenge.methods[0], body })","handlingStrategy":"validation","validationCode":"const challenge = await authModule.retrieveAuthMfaChallenge(challengeId)\nif (!challenge.methods.includes(method)) throw new Error(`Use one of: ${challenge.methods.join(', ')}`)","typeGuard":"const isSupportedMethod = (m: string, challenge: AuthMfaChallengeDTO): boolean => challenge.methods.includes(m)","tryCatchPattern":"null","preventionTips":["Read the challenge's methods array before choosing the verification method","Keep method strings consistent between create and verify"],"tags":["mfa","challenge","validation"],"backgroundTag":"method-not-allowed","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}