payloadcms/payload · error · NotFound
Not Found
Error message
Not Found
What it means
Thrown by `getDuplicateDocumentData` when the source document for duplication is not found AND the collection's read access is not a where-policy. Payload first applies read access, fetches the latest version, and if nothing comes back with a plain boolean access result it responds HTTP 404. This mirrors updateByID's not-found semantics for the duplicate operation.
Source
Thrown at packages/payload/src/duplicateDocument/index.ts:73
let duplicatedFromDocWithLocales = await getLatestCollectionVersion({
id,
config: collectionConfig,
payload,
query: findOneArgs,
req,
})
if (selectedLocales && selectedLocales.length > 0 && duplicatedFromDocWithLocales) {
duplicatedFromDocWithLocales = filterDataToSelectedLocales({
configBlockReferences: payload.config.blocks,
docWithLocales: duplicatedFromDocWithLocales,
fields: collectionConfig.fields,
selectedLocales,
})
}
if (!duplicatedFromDocWithLocales && !hasWherePolicy) {
throw new NotFound(req.t)
}
if (!duplicatedFromDocWithLocales && hasWherePolicy) {
throw new Forbidden(req.t)
}
// remove the createdAt timestamp and rely on the db to set it
if ('createdAt' in duplicatedFromDocWithLocales) {
delete duplicatedFromDocWithLocales.createdAt
}
// remove the id and rely on the db to set it
if ('id' in duplicatedFromDocWithLocales) {
delete duplicatedFromDocWithLocales.id
}
duplicatedFromDocWithLocales = await beforeDuplicate({
id,
collection: collectionConfig,
context: req.context,View on GitHub (pinned to 00c58b35c0)
Solutions
- Verify the source id exists (`payload.findByID`) before duplicating.
- Surface a 'source not found' message to the user; do not retry.
- If trash is enabled, ensure the source is not soft-trashed or operate with `trash: true`.
Example fix
// before
await payload.duplicate({ collection: 'posts', id })
// after
const src = await payload.findByID({ collection: 'posts', id }).catch(() => null)
if (!src) throw new Error('source post not found')
await payload.duplicate({ collection: 'posts', id }) Defensive patterns
Strategy: validation
Validate before calling
const src = await payload.findByID({ collection, id, depth: 0, req }).catch(() => null)
if (!src) throw new Error(`Source ${id} not found; cannot duplicate`)
await payload.duplicate({ collection, id, req }) Try / catch
try {
await payload.duplicate({ collection, id, req })
} catch (err) {
if (err instanceof NotFound) return respond(404, 'Source document not found')
throw err
} Prevention
- Existence-check the source id before duplicating.
- Disable duplicate UI actions for ids known to be deleted.
- Handle 404s gracefully in the client.
When it happens
Trigger: Calling `payload.duplicate({ id: '999' })` on a non-existent id; duplicating a hard-deleted document; the source id belongs to another collection.
Common situations: Stale 'duplicate' button in the UI pointing at a deleted doc; scripted duplication over a list where one id was removed; trashed source with `trash` not enabled in the lookup.
Related errors
- Not Found
- The collection with slug ${String(collectionSlug)} can't be
- The collection with slug ${String(collectionSlug)} cannot be
- Not Found
- Missing ID of document to update.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/bd64bf2214831d04.
Report an issue: GitHub.