payloadcms/payload · error · Forbidden

You are not allowed to perform this action.

Error message

You are not allowed to perform this action.

What it means

In `deleteByIDOperation`, if `docToDelete` is null AND `hasWhereAccess` is true, it throws `Forbidden`. The user's `access.delete` returned a where-constraint that excluded this document, so Payload signals denial rather than revealing existence.

Source

Thrown at packages/payload/src/collections/operations/deleteByID.ts:132

    // Exclude trashed documents when trash: false
    where = appendNonTrashedFilter({
      enableTrash: collectionConfig.trash,
      trash,
      where,
    })

    const docToDelete = await req.payload.db.findOne({
      collection: collectionConfig.slug,
      locale: req.locale!,
      req,
      where,
    })

    if (!docToDelete && !hasWhereAccess) {
      throw new NotFound(req.t)
    }
    if (!docToDelete && hasWhereAccess) {
      throw new Forbidden(req.t)
    }

    // /////////////////////////////////////
    // Handle potentially locked documents
    // /////////////////////////////////////

    await checkDocumentLockStatus({
      id,
      collectionSlug: collectionConfig.slug,
      lockErrorMessage: `Document with ID ${id} is currently locked and cannot be deleted.`,
      overrideLock,
      req,
    })

    await deleteAssociatedFiles({
      collectionConfig,
      config,
      doc: docToDelete!,

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Verify the user actually has delete access to that document.
  2. Use `overrideAccess: true` in trusted server-side code.
  3. Adjust the collection's `access.delete` function if it is too restrictive.

Example fix

// before
await payload.deleteByID({ collection: 'posts', id })
// after (server-side privileged)
await payload.deleteByID({ collection: 'posts', id, overrideAccess: true })
Defensive patterns

Strategy: try-catch

Type guard

function isForbidden(e): boolean {
  return e?.statusCode === 403 || e?.name === 'Forbidden'
}

Try / catch

try {
  await payload.deleteByID({ collection, id })
} catch (e) {
  if (isForbidden(e)) notifyUser('You do not have permission to delete this.')
  else throw e
}

Prevention

When it happens

Trigger: Deleting a document where the user's `access.delete` returns a `where` clause and no document matches both the requested ID and that access constraint.

Common situations: Role-based access control; multi-tenant setup where a user may only delete their own docs; the doc is owned by another user.

Related errors


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