payloadcms/payload · error · NotFound

Not Found

Error message

Not Found

What it means

Thrown during updateByID when `getLatestCollectionVersion` returns no document AND the collection's update access policy is not a where-policy (i.e. access is a simple boolean true). It means no document matches the given id, so Payload responds HTTP 404. The absence of a where-policy means there is no access restriction to hide, so a plain Not Found is correct.

Source

Thrown at packages/payload/src/collections/operations/updateByID.ts:171

    const findOneArgs: FindOneArgs = {
      collection: collectionConfig.slug,
      locale: locale!,
      req,
      where: fullWhere,
    }

    const docWithLocales = await getLatestCollectionVersion<
      RequiredDataFromCollectionSlug<TSlug> & TypeWithID
    >({
      id,
      config: collectionConfig,
      payload,
      query: findOneArgs,
      req,
    })

    if (!docWithLocales && !hasWherePolicy) {
      throw new NotFound(req.t)
    }
    if (!docWithLocales && hasWherePolicy) {
      throw new Forbidden(req.t)
    }
    if (!docWithLocales) {
      throw new NotFound(req.t)
    }

    // /////////////////////////////////////
    // Generate data for all files and sizes
    // /////////////////////////////////////

    const { data: newFileData, files: filesToUpload } = await generateFileData({
      collection,
      config,
      data,
      operation: 'update',
      overwriteExistingFiles,

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Confirm the id exists with `payload.findByID({ id, collection })` (or a count) before updating.
  2. If trash is enabled, pass `trash: true` to operate on trashed documents.
  3. Handle the 404 in the caller and surface a user-friendly 'not found' message instead of retrying.

Example fix

// before
await payload.update({ collection: 'posts', id, data })
// after
const exists = await payload.findByID({ collection: 'posts', id }).catch(() => null)
if (!exists) throw new NotFoundError('post not found')
await payload.update({ collection: 'posts', id, data })
Defensive patterns

Strategy: try-catch

Validate before calling

const exists = await payload.findByID({ collection, id, depth: 0, req }).catch(() => null)
if (!exists) {
  throw new Error(`Document ${id} not found; cannot update.`)
}
await payload.update({ collection, id, data, req })

Try / catch

try {
  await payload.update({ collection, id, data, req })
} catch (err) {
  if (err instanceof NotFound) {
    // document does not exist — inform the user, do not retry blindly
    return respond(404, 'Document not found')
  }
  throw err
}

Prevention

When it happens

Trigger: `payload.update({ id: '999' })` where id 999 does not exist; updating a document that was hard-deleted; passing an id from the wrong collection; trashed documents being excluded because `trash: false` (the default).

Common situations: Stale client holding an id from a deleted record; race where another request deletes the doc between read and update; the document is soft-trashed (trash enabled) and the update omits `trash: true`.

Related errors


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