medusajs/medusa · error · MedusaError

MFA factor with id "${id}" was not found

Error message

MFA factor with id "${id}" was not found

What it means

Thrown by AuthModuleService.retrieveAuthMfa when no MFA factor matches the given selector (id string or selector object). It is a NOT_FOUND MedusaError, meaning the caller referenced an MFA factor that does not exist (or was already deleted) in the auth module.

Source

Thrown at packages/modules/auth/src/services/auth-module.ts:591

  ): Promise<AuthTypes.AuthMfaDTO> {
    const filters =
      typeof selector === "string"
        ? { id: [selector] }
        : {
            id: [selector.id],
            auth_identity_id: selector.auth_identity_id,
          }

    const [factor] = await this.authMfaFactorService_.list(
      filters,
      config,
      sharedContext
    )

    if (!factor) {
      const id = typeof selector === "string" ? selector : selector.id

      throw new MedusaError(
        MedusaError.Types.NOT_FOUND,
        `MFA factor with id "${id}" was not found`
      )
    }

    return await this.serializeMfaFactor_(factor)
  }

  @InjectManager()
  async listAuthMfa(
    filters: AuthTypes.FilterableAuthMfaProps = {},
    config: FindConfig<AuthTypes.AuthMfaDTO> = {},
    @MedusaContext() sharedContext: Context = {}
  ): Promise<AuthTypes.AuthMfaDTO[]> {
    const factors = await this.authMfaFactorService_.list(
      filters,
      config,
      sharedContext

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Verify the factor id exists first with listAuthMfaFactors({ auth_identity_id }) before retrieving
  2. Catch MedusaError with type NOT_FOUND and prompt the user to re-enroll MFA
  3. Ensure you are not reusing ids from a previous database/seed

Example fix

// before
const factor = await authModule.retrieveAuthMfa(factorId)
// after
const factors = await authModule.listAuthMfaFactors({ auth_identity_id: identityId })
const factor = factors.find((f) => f.id === factorId)
if (!factor) throw new Error('Factor no longer enrolled; re-enroll MFA')
Defensive patterns

Strategy: try-catch

Validate before calling

const factors = await authModule.listAuthMfaFactors({ auth_identity_id: identityId })
const exists = factors.some((f) => f.id === factorId)
if (!exists) return reenrollMfa()

Type guard

const isMfaFactorId = (id: string): boolean => /^mfactor_/.test(id)

Try / catch

try { return await authModule.retrieveAuthMfa(factorId) } catch (e) { if (e.type === 'not_found') return reenrollMfa(); throw e }

Prevention

When it happens

Trigger: Calling authModuleService.retrieveAuthMfa('mfactor_123') or with a selector object whose id does not exist; calling after the factor was removed via removeAuthMfaFactor; passing an id belonging to a different auth identity.

Common situations: Stale factor id persisted in client/UI state after re-registering MFA; deleting and recreating factors during testing; race where another session removed the factor.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/eeeab95fd48b75c1. Report an issue: GitHub.