{"record":{"id":"91546f4e83b64bee","repo":"medusajs/medusa","slug":"disabled-mfa-factors-cannot-be-verified","errorCode":null,"errorMessage":"Disabled MFA factors cannot be verified","messagePattern":"Disabled MFA factors cannot be verified","errorType":"exception","errorClass":"MedusaError","httpStatus":403,"severity":"error","filePath":"packages/modules/auth/src/providers/mfa/totp.ts","lineNumber":139,"sourceCode":"  async verifySetup(\n    data: AuthTypes.AuthMfaVerifyDTO,\n    sharedContext: Context = {}\n  ): Promise<AuthTypes.AuthMfaDTO> {\n    const factor = await this.authMfaFactorService_.retrieve(\n      data.id,\n      {},\n      sharedContext\n    )\n\n    if (factor.provider !== this.method) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"Only TOTP MFA factors can be verified with this method\"\n      )\n    }\n\n    if (factor.status === \"disabled\") {\n      throw new MedusaError(\n        MedusaError.Types.NOT_ALLOWED,\n        \"Disabled MFA factors cannot be verified\"\n      )\n    }\n\n    const valid = this.verifyCode_(factor, data.code)\n\n    if (!valid) {\n      throw new MedusaError(MedusaError.Types.NOT_ALLOWED, \"Invalid TOTP code\")\n    }\n\n    const verifiedFactor =\n      factor.status === \"pending\"\n        ? await this.authMfaFactorService_.update(\n            { id: factor.id, status: \"enabled\" },\n            sharedContext\n          )\n        : factor","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/auth/src/providers/mfa/totp.ts#L121-L157","documentation":"The TOTP factor exists and is a TOTP factor, but its status is 'disabled'. Disabled factors cannot be verified; they must be re-enabled (or a new factor created) before use.","triggerScenarios":"confirmAuthMfaFactor with the id of a factor whose status was set to 'disabled' (previously disabled by the user or an admin) while still passing a code to verify.","commonSituations":"User disabled authenticator MFA, stale frontend state still shows the old setup and submits its code; scripts verifying factors listed without filtering by status.","solutions":["Filter factor lists by status === 'enabled' or 'pending' before offering verification","Start a new TOTP setup for the identity instead of verifying the disabled factor"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (factor.status === 'disabled') { /* restart setup instead of verifying */ }","typeGuard":"const isVerifiable = (f: { status: string }) => f.status === 'enabled' || f.status === 'pending'","tryCatchPattern":null,"preventionTips":["Filter factor lists by status before offering verification","Clear stale factor state in the UI after disable"],"tags":["auth","mfa","totp","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}