OrchardCMS/OrchardCore · error · FileStoreException
Cannot copy file ' ' because it does not exist.
Error message
Cannot copy file '${srcPath}' because it does not exist. What it means
CopyFileAsync first calls GetObjectMetadataAsync to verify the source file exists. When S3 returns a 404 (AmazonS3Exception with HttpStatusCode.NotFound), the method wraps it in a FileStoreException stating the source file does not exist, since there is nothing to copy.
Solutions
- Verify the file exists with fileStore.GetFileExistsAsync(srcPath) (or IFileStore.FileExists) before copying.
- Check the S3 BucketName and BasePath options point to the bucket/prefix that actually holds the file.
- Confirm the exact key exists in the S3 console/CLI (aws s3 ls), including case.
- Handle FileStoreException in the caller and report a friendly 'file not found' message.
Example fix
// before
await fileStore.CopyFileAsync(srcPath, dstPath);
// after
if (!await fileStore.GetFileExistsAsync(srcPath))
{
throw new InvalidOperationException($"Source '{srcPath}' does not exist.");
}
await fileStore.CopyFileAsync(srcPath, dstPath); Defensive patterns
Strategy: try-catch
Validate before calling
if (!await fileStore.GetFileExistsAsync(srcPath))
{
throw new FileNotFoundException($"Source file '{srcPath}' was not found.", srcPath);
} Try / catch
try
{
await fileStore.CopyFileAsync(srcPath, dstPath);
}
catch (FileStoreException ex) when (ex.Message.Contains("does not exist"))
{
_logger.LogWarning("Copy skipped, missing source '{Src}'", srcPath);
} Prevention
- Check existence before copy/move operations.
- Validate BucketName/BasePath configuration at startup.
- Remember S3 keys are case-sensitive; store canonical paths.
When it happens
Trigger: CopyFileAsync(srcPath, dstPath) where no object exists at the combined base prefix + srcPath key in the bucket; also surfaced through MoveFileAsync.
Common situations: Wrong bucket or BasePath configured in the AWS S3 options, typo in the path, file was deleted by another process/tenant, case-sensitivity mismatch (S3 keys are case-sensitive), media file removed before a copy/move operation.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Error retrieving file info for
- Error creating directory
- Error deleting file
- Cannot delete root directory.
- The values for and must not be the same.
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/f929973268589dd4.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.FileStorage.AmazonS3/AwsFileStorage.cs:211
public async Task CopyFileAsync(string srcPath, string dstPath)
{
if (srcPath == dstPath)
{
throw new ArgumentException($"The values for {nameof(srcPath)} and {nameof(dstPath)} must not be the same.");
}
try
{
await _amazonS3Client.GetObjectMetadataAsync(new GetObjectMetadataRequest
{
BucketName = _options.BucketName,
Key = this.Combine(_basePrefix, srcPath),
});
}
catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
throw new FileStoreException($"Cannot copy file '{srcPath}' because it does not exist.");
}
catch (AmazonS3Exception ex)
{
throw new FileStoreException($"Error accessing file '{srcPath}': {ex.Message}", ex);
}
try
{
var listObjects = await _amazonS3Client.ListObjectsV2Async(new ListObjectsV2Request
{
BucketName = _options.BucketName,
Prefix = this.Combine(_basePrefix, dstPath),
});
if (listObjects.S3Objects?.Count > 0)
{
throw new ExistsFileStoreException($"Cannot copy file '{srcPath}' because a file already exists in the new path '{dstPath}'.");
}View on GitHub (pinned to 4306c0717f)