{"record":{"id":"301f90d64fbe5327","repo":"nextcloud/server","slug":"permission-denied-to-rename-the-trashbin","errorCode":null,"errorMessage":"Permission denied to rename the trashbin","messagePattern":"Permission denied to rename the trashbin","errorType":"exception","errorClass":"Forbidden","httpStatus":403,"severity":"error","filePath":"apps/dav/lib/CalDAV/Trashbin/TrashbinHome.php","lineNumber":119,"sourceCode":"\t\treturn in_array($name, [\n\t\t\tRestoreTarget::NAME,\n\t\t\tDeletedCalendarObjectsCollection::NAME,\n\t\t], true);\n\t}\n\n\t#[\\Override]\n\tpublic function delete() {\n\t\tthrow new Forbidden('Permission denied to delete the trashbin');\n\t}\n\n\t#[\\Override]\n\tpublic function getName(): string {\n\t\treturn self::NAME;\n\t}\n\n\t#[\\Override]\n\tpublic function setName($name) {\n\t\tthrow new Forbidden('Permission denied to rename the trashbin');\n\t}\n\n\t#[\\Override]\n\tpublic function getLastModified(): int {\n\t\treturn 0;\n\t}\n\n\t#[\\Override]\n\tpublic function propPatch(PropPatch $propPatch): void {\n\t\tthrow new Forbidden('not implemented');\n\t}\n\n\t#[\\Override]\n\tpublic function getProperties($properties): array {\n\t\treturn [\n\t\t\t'{DAV:}resourcetype' => new ResourceType([\n\t\t\t\t'{DAV:}collection',\n\t\t\t\tsprintf('{%s}trash-bin', \\OCA\\DAV\\DAV\\Sharing\\Plugin::NS_NEXTCLOUD),","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/nextcloud/server/blob/ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3/apps/dav/lib/CalDAV/Trashbin/TrashbinHome.php#L101-L137","documentation":"TrashbinHome::setName() throws Sabre\\DAV\\Exception\\Forbidden: DAV renames are expressed as MOVE with a Destination header, and the 'trashbin' segment under the calendar home is a fixed system path derived from the principal URI. Any MOVE that would rename or relocate the trashbin collection itself returns HTTP 403.","triggerScenarios":"MOVE with a Destination header renaming /remote.php/dav/calendars/<user>/trashbin; drag-and-drop reorganization in a DAV browser; batch renamers that iterate all discovered collections.","commonSituations":"GUI DAV clients that permit renaming any collection node; scripts relocating subtrees after principal or instance migrations.","solutions":["Exclude the trashbin from rename/move batches - its path is fixed","To get data out of the trashbin, MOVE objects into trashbin/restore (restore); the collection itself stays put","Treat a MOVE 403 on the trashbin as terminal, not retryable"],"exampleFix":"// before\nMOVE /remote.php/dav/calendars/alice/trashbin\nDestination: /remote.php/dav/calendars/alice/bin/\n-> 403 Permission denied to rename the trashbin\n\n// after: move objects, not the collection\nMOVE /remote.php/dav/calendars/alice/trashbin/objects/event-42.ics\nDestination: /remote.php/dav/calendars/alice/trashbin/restore/event-42.ics","handlingStrategy":"validation","validationCode":"if (rtrim($moveSource, '/') === \"/remote.php/dav/calendars/{$user}/trashbin\") {\n    return; // the trashbin collection cannot be renamed or relocated\n}","typeGuard":null,"tryCatchPattern":"try {\n    $client->request('MOVE', $uri, null, $destination);\n} catch (\\Sabre\\HTTP\\ClientHttpException $e) {\n    if ($e->getResponse()->getStatus() === 403 && str_ends_with(rtrim($uri, '/'), '/trashbin')) {\n        return; // fixed system path: not renameable\n    }\n    throw $e;\n}","preventionTips":["Filter fixed system segments (trashbin) out of rename/move target lists","MOVE objects into trashbin/restore to undelete; leave the collection itself untouched","Treat MOVE 403 on system collections as terminal, not retryable"],"tags":["caldav","dav","trashbin","http-403","move"],"backgroundTag":"dav-403-forbidden","analyzedSha":"ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3","analyzedAt":"2026-08-17T01:36:13.386Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}