{"record":{"id":"f445428bc12792c6","repo":"OrchardCMS/OrchardCore","slug":"cannot-copy-file-srcpath-to-dstpath-filesystemstore","errorCode":null,"errorMessage":"Cannot copy file '{srcPath}' to '{dstPath}'.","messagePattern":"Cannot copy file '(.+?)' to '(.+?)'\\.","errorType":"exception","errorClass":"FileStoreException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.FileStorage.FileSystem/FileSystemStore.cs","lineNumber":303,"sourceCode":"\n            var physicalDstPath = GetPhysicalPath(dstPath);\n\n            if (File.Exists(physicalDstPath) || Directory.Exists(physicalDstPath))\n            {\n                throw new FileStoreException($\"Cannot copy file because the destination path '{dstPath}' already exists.\");\n            }\n\n            File.Copy(GetPhysicalPath(srcPath), GetPhysicalPath(dstPath));\n\n            return Task.CompletedTask;\n        }\n        catch (FileStoreException)\n        {\n            throw;\n        }\n        catch (Exception ex)\n        {\n            throw new FileStoreException($\"Cannot copy file '{srcPath}' to '{dstPath}'.\", ex);\n        }\n    }\n\n    public Task<Stream> GetFileStreamAsync(string path)\n    {\n        try\n        {\n            var physicalPath = GetPhysicalPath(path);\n\n            if (!File.Exists(physicalPath))\n            {\n                throw new FileStoreException($\"Cannot get file stream because the file '{path}' does not exist.\");\n            }\n\n            var stream = File.OpenRead(physicalPath);\n\n            return Task.FromResult<Stream>(stream);\n        }","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.FileStorage.FileSystem/FileSystemStore.cs#L285-L321","documentation":"Wrapped FileStoreException from FileSystemStore.CopyFileAsync: File.Copy itself threw after both pre-flight checks passed (source disappeared, permission error, disk full, path issues). Deliberate rejections like a missing source or existing destination are rethrown as-is; this variant wraps unexpected I/O failures.","triggerScenarios":"File.Copy failing due to a locked source or destination, insufficient permissions, invalid mapped path, or a destination created concurrently between the check and the copy.","commonSituations":"Media folder permissions wrong for the app identity; file locked by another handler; race with a concurrent request copying to the same destination.","solutions":["Read InnerException to identify the real IO failure.","Fix write permissions on the destination directory.","Retry with backoff, and serialize copies to the same destination."],"exampleFix":"// before\nawait store.CopyFileAsync(src, dst); // transient lock\n// after\ntry { await store.CopyFileAsync(src, dst); }\ncatch (FileStoreException ex) { _logger.LogError(ex.InnerException, \"Copy failed\"); throw; }","handlingStrategy":"try-catch","validationCode":"if (await store.GetFileInfoAsync(srcPath) is null) throw new InvalidOperationException(\"missing source\");\nif (await store.GetFileInfoAsync(dstPath) is not null) throw new InvalidOperationException(\"destination taken\");","typeGuard":null,"tryCatchPattern":"try { await store.CopyFileAsync(srcPath, dstPath); }\ncatch (FileStoreException ex)\n{\n    _logger.LogError(ex.InnerException, \"Copy {Src} -> {Dst} failed\", srcPath, dstPath);\n    throw;\n}","preventionTips":["Verify storage-root write permissions for the app identity.","Retry transient failures with backoff.","Dispose sources/streams that could lock files during the copy."],"tags":["filesystem","io","file-copy"],"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"}