payloadcms/payload · warning · NotFound

Not Found

Error message

Not Found

What it means

Thrown by preferences `deleteOperation` after `payload.db.deleteOne` returns no result. The where clause filters by `key`, `user.value`, and `user.relationTo`; if zero rows match (key does not exist for this user), the DB returns nothing and the operation raises NotFound rather than silently no-op.

Source

Thrown at packages/payload/src/preferences/operations/delete.ts:37

  const where: Where = {
    and: [
      { key: { equals: key } },
      { 'user.value': { equals: user.id } },
      { 'user.relationTo': { equals: user.collection } },
    ],
  }

  const result = await payload.db.deleteOne({
    collection: preferencesCollectionSlug,
    req,
    where,
  })

  if (result) {
    return result
  }
  throw new NotFound(req.t)
}

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Check existence before deleting (findOne by key+user) and treat missing as success if idempotency is desired.
  2. Wrap the delete in try/catch and ignore a 404 when the operation should be idempotent.
  3. Verify the exact key string matches what was stored.

Example fix

// before
await payload.delete({ collection: 'payload-preferences', id: key, req })

// after
try {
  await payload.delete({ collection: 'payload-preferences', id: key, req })
} catch (err) {
  if (err.statusCode !== 404) throw err
}
Defensive patterns

Strategy: try-catch

Validate before calling

import type { Where } from 'payload'

async function preferenceExists(payload, key: string, req): Promise<boolean> {
  const where: Where = {
    and: [
      { key: { equals: key } },
      { 'user.value': { equals: req.user.id } },
      { 'user.relationTo': { equals: req.user.collection } },
    ],
  }
  const { totalDocs } = await payload.count({ collection: 'payload-preferences', where, req })
  return totalDocs > 0
}

Try / catch

import { APIError } from 'payload'

try {
  await payload.delete({ collection: 'payload-preferences', id: key, req })
} catch (err) {
  if (err instanceof APIError && err.statusCode === 404) {
    // already gone; treat as success (idempotent delete)
  } else throw err
}

Prevention

When it happens

Trigger: Deleting a preference key that the current user never created, or that belongs to a different user; passing a wrong/typo key; deleting twice (second call finds nothing).

Common situations: UI sends a delete for a preference that was reset elsewhere; race condition where another session deleted it first; key mismatch (camelCase vs stored key).

Related errors


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