{"record":{"id":"f3c2b9bc061c0ce6","repo":"OrchardCMS/OrchardCore","slug":"cannot-delete-directory-path-filesystemstore","errorCode":null,"errorMessage":"Cannot delete directory '{path}'.","messagePattern":"Cannot delete directory '(.+?)'\\.","errorType":"exception","errorClass":"FileStoreException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.FileStorage.FileSystem/FileSystemStore.cs","lineNumber":239,"sourceCode":"\n    public Task<bool> TryDeleteDirectoryAsync(string path)\n    {\n        try\n        {\n            var physicalPath = GetPhysicalPath(path);\n\n            if (!Directory.Exists(physicalPath))\n            {\n                return Task.FromResult(false);\n            }\n\n            Directory.Delete(physicalPath, recursive: true);\n\n            return Task.FromResult(true);\n        }\n        catch (Exception ex)\n        {\n            throw new FileStoreException($\"Cannot delete directory '{path}'.\", ex);\n        }\n    }\n\n    public Task MoveFileAsync(string oldPath, string newPath)\n    {\n        try\n        {\n            var physicalOldPath = GetPhysicalPath(oldPath);\n\n            if (!File.Exists(physicalOldPath))\n            {\n                throw new FileStoreException($\"Cannot move file '{oldPath}' because it does not exist.\");\n            }\n\n            var physicalNewPath = GetPhysicalPath(newPath);\n\n            if (File.Exists(physicalNewPath) || Directory.Exists(physicalNewPath))\n            {","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.FileStorage.FileSystem/FileSystemStore.cs#L221-L257","documentation":"Catch-all in TryDeleteDirectoryAsync: Directory.Delete(recursive: true) threw an unexpected exception, rethrown as FileStoreException. A non-existent directory returns false instead; this message means the recursive delete failed partway.","triggerScenarios":"TryDeleteDirectoryAsync(path) when a file inside the tree is locked, a subdirectory denies access, or the path is invalid.","commonSituations":"Nested file opened by another request during deletion; Windows directory-in-use; permission issues deep in the tree; files recreated concurrently by an indexing job.","solutions":["Check InnerException for the specific failing path.","Stop background jobs/streams touching that directory and retry.","Fix ACLs on the directory tree."],"exampleFix":"// before\nawait store.TryDeleteDirectoryAsync(\"uploads/temp\"); // job still writing there\n// after\nawait _indexingJob.PauseAsync();\nawait store.TryDeleteDirectoryAsync(\"uploads/temp\");\nawait _indexingJob.ResumeAsync();","handlingStrategy":"try-catch","validationCode":"var dir = await store.GetDirectoryInfoAsync(path);\nif (dir is null) return; // TryDeleteDirectoryAsync would just return false","typeGuard":null,"tryCatchPattern":"try { await store.TryDeleteDirectoryAsync(path); }\ncatch (FileStoreException ex)\n{\n    _logger.LogError(ex.InnerException, \"Recursive delete failed for {Path}\", path);\n    throw;\n}","preventionTips":["Pause background jobs that write into the directory before deleting it.","Avoid deleting directories while requests may hold streams inside them.","Ensure ACLs allow recursive deletion of the subtree."],"tags":["filesystem","io","directory-delete"],"backgroundTag":"file-write-failed","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}