{"record":{"id":"c05d407e75358caf","repo":"payloadcms/payload","slug":"cannot-restore-a-version-of-a-trashed-document-id","errorCode":null,"errorMessage":"Cannot restore a version of a trashed document (ID: ${parentDocID}). Restore the document first.","messagePattern":"Cannot restore a version of a trashed document \\(ID: (.+?)\\)\\. Restore the document first\\.","errorType":"http","errorClass":"APIError","httpStatus":403,"severity":"error","filePath":"packages/payload/src/collections/operations/restoreVersion.ts","lineNumber":133,"sourceCode":"    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,\n    })\n\n    // originalDoc with hoisted localized data\n    const validationLocale = payload.config.localization","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/collections/operations/restoreVersion.ts#L115-L151","documentation":"Thrown at packages/payload/src/collections/operations/restoreVersion.ts:133 with HTTP 403 (FORBIDDEN) during restoreVersion when the collection has `trash: true` enabled and the parent document is currently soft-deleted (`deletedAt` is set). Restoring a version onto a trashed document is disallowed because the document must first be restored from the trash bin.","triggerScenarios":"A document was soft-deleted (moved to trash) and a user (or automation) attempts to restore one of its versions before restoring the parent document itself; the admin UI lists versions for a trashed doc and allows the restore action.","commonSituations":"Trash/soft-delete feature enabled on the collection; orphaned UI state showing version actions for trashed docs; automation that runs restoreVersion without checking trash status.","solutions":["Restore the parent document from trash first (e.g., `payload.update({ collection, id, data: { deletedAt: null } })` with trash enabled), then call restoreVersion.","Hide the 'Restore version' action in the UI when the parent document is trashed.","Check `doc.deletedAt` before attempting version restore."],"exampleFix":"// before\nawait payload.restoreVersion({ collection: 'pages', id: versionId }) // parent is trashed\n\n// after — restore the parent from trash first\nawait payload.update({ collection: 'pages', id: parentDocID, data: { deletedAt: null } })\nawait payload.restoreVersion({ collection: 'pages', id: versionId })","handlingStrategy":"validation","validationCode":"// Restore the parent from trash before restoring a version\nconst parent = await payload.findByID({ collection: 'pages', id: parentDocID, overrideAccess: true })\nif (parent?.deletedAt) {\n  // parent is trashed — restore it first\n  await payload.update({ collection: 'pages', id: parentDocID, data: { deletedAt: null } })\n}\nawait payload.restoreVersion({ collection: 'pages', id: versionId })","typeGuard":"const isTrashed = (doc: { deletedAt?: string | null } | null): doc is { deletedAt: string } =>\n  Boolean(doc && typeof doc.deletedAt === 'string' && doc.deletedAt)\n\nif (!isTrashed(parent)) {\n  await payload.restoreVersion({ collection: 'pages', id: versionId })\n}","tryCatchPattern":"try {\n  await payload.restoreVersion({ collection: 'pages', id: versionId })\n} catch (err) {\n  if (err instanceof APIError && err.status === 403 && /trashed document/.test(err.message)) {\n    // restore the parent from trash, then retry restoreVersion\n  } else throw err\n}","preventionTips":["Hide version Restore actions in the UI when the parent document is trashed.","Check `doc.deletedAt` before attempting version restore.","Ensure trash-restore and version-restore flows are presented in the correct order."],"tags":["local-api","restore-version","trash","soft-delete","forbidden"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}