payloadcms/payload · error · Forbidden

error:notAllowedToPerformAction

Error message

error:notAllowedToPerformAction

What it means

Thrown in `resetPassword` when `collectionConfig.auth.disableLocalStrategy` is true. The collection does not store local credentials, so resetting a password locally is not applicable. `Forbidden` (HTTP 403).

Source

Thrown at packages/payload/src/auth/operations/resetPassword.ts:59

    data,
    depth,
    overrideAccess,
    req: {
      payload: { secret },
      payload,
    },
    req,
  } = args

  if (
    !Object.prototype.hasOwnProperty.call(data, 'token') ||
    !Object.prototype.hasOwnProperty.call(data, 'password')
  ) {
    throw new APIError('Missing required data.', httpStatus.BAD_REQUEST)
  }

  if (collectionConfig.auth.disableLocalStrategy) {
    throw new Forbidden(req.t)
  }

  let sid: string | undefined
  let user: null | User = null

  try {
    const shouldCommit = await initTransaction(req)

    args = await buildBeforeOperation({
      args,
      collection: args.collection.config,
      operation: 'resetPassword',
      overrideAccess,
    })

    // /////////////////////////////////////
    // Reset Password
    // /////////////////////////////////////

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Route password resets only to collections with a local strategy (`disableLocalStrategy: false`).
  2. For external-strategy collections, perform password reset through the IdP instead.
  3. Branch client logic: skip the Payload reset call when `auth.disableLocalStrategy` is true.

Example fix

// before
await payload.resetPassword({ collection: 'users', data, req })
// after
if (!collectionConfig.auth.disableLocalStrategy) {
  await payload.resetPassword({ collection: 'users', data, req })
}
Defensive patterns

Strategy: validation

Validate before calling

// Only reset passwords for local-strategy collections
if (collectionConfig.auth.disableLocalStrategy) {
  throw new Error('Password reset is unavailable for this collection')
}
await payload.resetPassword({ collection, data, req })

Type guard

function supportsLocalPassword(cfg: CollectionConfig): boolean {
  return !cfg.auth?.disableLocalStrategy
}

Try / catch

if (collectionConfig.auth.disableLocalStrategy) {
  // route to the IdP's password-reset flow
} else {
  await payload.resetPassword({ collection, data, req })
}

Prevention

When it happens

Trigger: A collection configured with `auth: { disableLocalStrategy: true }` (external IdP / JWT strategy) receives a reset-password request. Payload bails before touching credentials.

Common situations: Pointing the reset-password flow at an SSO-only collection; a shared frontend that doesn't branch on `disableLocalStrategy`; misconfiguring a collection that should handle passwords locally.

Related errors


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/ca97ee7625f34aee. Report an issue: GitHub.