OrchardCMS/OrchardCore · error · FileStoreException

Cannot delete directory

Error message

Cannot delete directory '{path}'.

What it means

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.

Solutions

  1. Check InnerException for the specific failing path.
  2. Stop background jobs/streams touching that directory and retry.
  3. Fix ACLs on the directory tree.

Example fix

// before
await store.TryDeleteDirectoryAsync("uploads/temp"); // job still writing there
// after
await _indexingJob.PauseAsync();
await store.TryDeleteDirectoryAsync("uploads/temp");
await _indexingJob.ResumeAsync();
Defensive patterns

Strategy: try-catch

Validate before calling

var dir = await store.GetDirectoryInfoAsync(path);
if (dir is null) return; // TryDeleteDirectoryAsync would just return false

Try / catch

try { await store.TryDeleteDirectoryAsync(path); }
catch (FileStoreException ex)
{
    _logger.LogError(ex.InnerException, "Recursive delete failed for {Path}", path);
    throw;
}

Prevention

When it happens

Trigger: TryDeleteDirectoryAsync(path) when a file inside the tree is locked, a subdirectory denies access, or the path is invalid.

Common situations: 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.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/f3c2b9bc061c0ce6. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.FileStorage.FileSystem/FileSystemStore.cs:239

    public Task<bool> TryDeleteDirectoryAsync(string path)
    {
        try
        {
            var physicalPath = GetPhysicalPath(path);

            if (!Directory.Exists(physicalPath))
            {
                return Task.FromResult(false);
            }

            Directory.Delete(physicalPath, recursive: true);

            return Task.FromResult(true);
        }
        catch (Exception ex)
        {
            throw new FileStoreException($"Cannot delete directory '{path}'.", ex);
        }
    }

    public Task MoveFileAsync(string oldPath, string newPath)
    {
        try
        {
            var physicalOldPath = GetPhysicalPath(oldPath);

            if (!File.Exists(physicalOldPath))
            {
                throw new FileStoreException($"Cannot move file '{oldPath}' because it does not exist.");
            }

            var physicalNewPath = GetPhysicalPath(newPath);

            if (File.Exists(physicalNewPath) || Directory.Exists(physicalNewPath))
            {

View on GitHub (pinned to 4306c0717f)