{"record":{"id":"750cbcec07f235e1","repo":"OrchardCMS/OrchardCore","slug":"cannot-copy-file-because-the-destination-path-dstpath","errorCode":null,"errorMessage":"Cannot copy file because the destination path '{dstPath}' already exists.","messagePattern":"Cannot copy file because the destination path '(.+?)' already exists\\.","errorType":"exception","errorClass":"FileStoreException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.FileStorage.FileSystem/FileSystemStore.cs","lineNumber":290,"sourceCode":"        }\n    }\n\n    public Task CopyFileAsync(string srcPath, string dstPath)\n    {\n        try\n        {\n            var physicalSrcPath = GetPhysicalPath(srcPath);\n\n            if (!File.Exists(physicalSrcPath))\n            {\n                throw new FileStoreException($\"The file '{srcPath}' does not exist.\");\n            }\n\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    {","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.FileStorage.FileSystem/FileSystemStore.cs#L272-L308","documentation":"Pre-flight check in FileSystemStore.CopyFileAsync: a file or directory already exists at the physical destination path. The store disallows overwriting on copy, so the operation is rejected before File.Copy is invoked.","triggerScenarios":"Calling CopyFileAsync(srcPath, dstPath) where dstPath already exists as a file or directory, e.g. re-running an import that copies into the same media folder.","commonSituations":"Re-running recipes/import steps without idempotency; copying with a destination name derived from the source name that already exists; concurrent uploads picking the same name.","solutions":["Delete the existing destination first or pick a unique destination name.","Make the copy step idempotent by checking GetFileInfoAsync(dstPath) and skipping if present.","Append a timestamp/GUID to generated destination names."],"exampleFix":"// before\nawait store.CopyFileAsync(src, \"media/photo.png\"); // exists on re-run\n// after\nif (await store.GetFileInfoAsync(\"media/photo.png\") is null)\n    await store.CopyFileAsync(src, \"media/photo.png\");","handlingStrategy":"validation","validationCode":"if (await store.GetFileInfoAsync(dstPath) is not null || await store.GetDirectoryInfoAsync(dstPath) is not null)\n    return; // already copied — make the step idempotent by skipping","typeGuard":null,"tryCatchPattern":"try { await store.CopyFileAsync(srcPath, dstPath); }\ncatch (FileStoreException ex) when (ex.Message.Contains(\"already exists\"))\n{\n    // skip or generate a unique destination\n}","preventionTips":["Make copy steps idempotent: skip when the destination exists.","Add a GUID/timestamp to generated destination filenames.","Guard against concurrent copies to the same destination."],"tags":["filesystem","file-store","destination-exists"],"backgroundTag":"file-already-exists","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"}