{"record":{"id":"ddcdd08720892b19","repo":"payloadcms/payload","slug":"you-are-not-allowed-to-perform-this-action-ddcdd0","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/collections/operations/restoreVersion.ts","lineNumber":129,"sourceCode":"    // /////////////////////////////////////\n    // Retrieve document\n    // /////////////////////////////////////\n\n    const findOneArgs: FindOneArgs = {\n      collection: collectionConfig.slug,\n      locale: 'all',\n      req,\n      where: combineQueries({ id: { equals: parentDocID } }, accessResults),\n    }\n\n    // Get the document from the non versioned collection\n    const doc = await req.payload.db.findOne<TData>(findOneArgs)\n\n    if (!doc && !hasWherePolicy) {\n      throw new NotFound(req.t)\n    }\n    if (!doc && hasWherePolicy) {\n      throw new Forbidden(req.t)\n    }\n\n    if (collectionConfig.trash && doc?.deletedAt) {\n      throw new APIError(\n        `Cannot restore a version of a trashed document (ID: ${parentDocID}). Restore the document first.`,\n        httpStatus.FORBIDDEN,\n      )\n    }\n\n    // /////////////////////////////////////\n    // fetch previousDoc\n    // /////////////////////////////////////\n    const prevDocWithLocales = await getLatestCollectionVersion({\n      id: parentDocID,\n      config: collectionConfig,\n      payload,\n      query: findOneArgs,\n      req,","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/collections/operations/restoreVersion.ts#L111-L147","documentation":"Thrown as `new Forbidden(req.t)` (HTTP 403) at packages/payload/src/collections/operations/restoreVersion.ts:129 during restoreVersion when the parent document is not found AND a where-based access policy is in effect. The distinction from error 155 matters: when access control returns a `where` clause and the doc is absent, Payload reports Forbidden (not NotFound) to avoid leaking the existence of documents the user cannot see.","triggerScenarios":"A user without update access attempts to restore a version of a document they cannot read; the collection's `access.update` returns a where filter that excludes the parent doc; the parent doc was deleted but the access policy is a where clause (so 403 is chosen over 404 to prevent information disclosure).","commonSituations":"Role-based access where the user's policy hides certain docs; a multi-tenant where clause (`tenant: { equals: currentUser.tenant }`) that does not match the version's parent; restoring across locales/tenants.","solutions":["Confirm the authenticated user has `update` access to the parent document's collection.","Inspect the collection's `access.update` function and the where clause it returns for this user.","If overriding access server-side is acceptable, pass `overrideAccess: true` (use sparingly and never with untrusted callers)."],"exampleFix":"// before — user lacks update access, restoreVersion throws Forbidden\nawait payload.restoreVersion({ collection: 'pages', id: versionId, req })\n\n// after — escalate to a service account that is allowed to update, or fix the access policy\nawait payload.restoreVersion({ collection: 'pages', id: versionId, overrideAccess: true, req })\n// (only in trusted server contexts; never expose overrideAccess:true to client input)","handlingStrategy":"try-catch","validationCode":"// Access policies are server-side; the reliable pre-check is a findByID with the user's req\nconst visible = await payload.findByID({\n  collection: 'pages',\n  id: parentDocID,\n  req, // applies the user's access.update where policy\n  disableErrors: true,\n})\nif (!visible) {\n  // user cannot see/update this document — do not attempt restoreVersion\n}","typeGuard":"// No static type guard applies; access is runtime-evaluated.\n// Expose a helper that runs the access check:\nconst canRestore = async (payload: Payload, collection: CollectionSlug, parentId: string | number, req: PayloadRequest) => {\n  const doc = await payload.findByID({ collection, id: parentId, req, disableErrors: true })\n  return Boolean(doc)\n}","tryCatchPattern":"try {\n  await payload.restoreVersion({ collection: 'pages', id: versionId, req })\n} catch (err) {\n  if (err instanceof Forbidden) {\n    // user lacks update access (or doc hidden by a where policy) — return 403\n  } else throw err\n}","preventionTips":["Never expose overrideAccess:true to client input; only use it in trusted server code.","Test restore flows under each role defined in access.update.","When access returns a where clause, treat 'not found' as 403 to avoid information leakage (Payload already does this internally)."],"tags":["local-api","restore-version","access-control","forbidden","security"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}