{"record":{"id":"3122da24ac356b9d","repo":"payloadcms/payload","slug":"you-are-not-allowed-to-perform-this-action-3122da","errorCode":null,"errorMessage":"You are not allowed to perform this action.","messagePattern":"You are not allowed to perform this action\\.","errorType":"http","errorClass":"Forbidden","httpStatus":403,"severity":"error","filePath":"packages/payload/src/duplicateDocument/index.ts","lineNumber":76,"sourceCode":"    payload,\n    query: findOneArgs,\n    req,\n  })\n\n  if (selectedLocales && selectedLocales.length > 0 && duplicatedFromDocWithLocales) {\n    duplicatedFromDocWithLocales = filterDataToSelectedLocales({\n      configBlockReferences: payload.config.blocks,\n      docWithLocales: duplicatedFromDocWithLocales,\n      fields: collectionConfig.fields,\n      selectedLocales,\n    })\n  }\n\n  if (!duplicatedFromDocWithLocales && !hasWherePolicy) {\n    throw new NotFound(req.t)\n  }\n  if (!duplicatedFromDocWithLocales && hasWherePolicy) {\n    throw new Forbidden(req.t)\n  }\n\n  // remove the createdAt timestamp and rely on the db to set it\n  if ('createdAt' in duplicatedFromDocWithLocales) {\n    delete duplicatedFromDocWithLocales.createdAt\n  }\n  // remove the id and rely on the db to set it\n  if ('id' in duplicatedFromDocWithLocales) {\n    delete duplicatedFromDocWithLocales.id\n  }\n\n  duplicatedFromDocWithLocales = await beforeDuplicate({\n    id,\n    collection: collectionConfig,\n    context: req.context,\n    doc: duplicatedFromDocWithLocales,\n    overrideAccess: overrideAccess!,\n    req,","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/duplicateDocument/index.ts#L58-L94","documentation":"Thrown by `getDuplicateDocumentData` when the source document is not found BUT a where-based read access policy is active. As with updateByID, Payload returns 403 rather than 404 to avoid revealing whether the document exists. The caller either lacks read access or the document is outside their where-clause scope.","triggerScenarios":"A user whose `access.read` returns `{ where: {...} }` tries to duplicate a document outside that scope; cross-tenant duplication; duplicating a private doc as a non-owner.","commonSituations":"Multi-tenant read scoping; role-based access where users can only see their own docs; an admin tool duplicating across tenants without `overrideAccess`.","solutions":["Confirm the caller has read access to the source document (run a scoped `findByID` first).","If the operation is privileged/internal, use `overrideAccess: true` deliberately.","Return a clear 'not allowed' message; do not leak existence by retrying different ids."],"exampleFix":"// before\nawait payload.duplicate({ collection: 'posts', id, req, overrideAccess: false })\n// after\nconst src = await payload.findByID({ collection: 'posts', id, req }) // enforces read access\nif (!src) throw new ForbiddenError('cannot duplicate this post')\nawait payload.duplicate({ collection: 'posts', id, req })","handlingStrategy":"try-catch","validationCode":"const src = await payload.findByID({ collection, id, req, depth: 0 }).catch(() => null)\nif (!src) throw new ForbiddenError('Cannot duplicate this document')\nawait payload.duplicate({ collection, id, req })","typeGuard":null,"tryCatchPattern":"try {\n  await payload.duplicate({ collection, id, req })\n} catch (err) {\n  if (err instanceof Forbidden) return respond(403, 'Not allowed')\n  throw err\n}","preventionTips":["Pre-check read access with a scoped findByID.","Use `overrideAccess: true` only for deliberate privileged duplication.","Return a uniform 403 to avoid leaking document existence."],"tags":["duplicate","collections","forbidden","access-control","security"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}