{"record":{"id":"5732b24bc3cd313b","repo":"abpframework/abp","slug":"saving-blob-args-blobname-does-already-exists-5732b2","errorCode":null,"errorMessage":"Saving BLOB '{args.BlobName}' does already exists in the container '{containerName}'! Set OverrideExisting if it should be overwritten.","messagePattern":"Saving BLOB '(.+?)' does already exists in the container '(.+?)'! Set OverrideExisting if it should be overwritten\\.","errorType":"exception","errorClass":"BlobAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProvider.cs","lineNumber":44,"sourceCode":"        IAmazonS3ClientFactory amazonS3ClientFactory,\n        IBlobNormalizeNamingService blobNormalizeNamingService)\n    {\n        AwsBlobNameCalculator = awsBlobNameCalculator;\n        AmazonS3ClientFactory = amazonS3ClientFactory;\n        BlobNormalizeNamingService = blobNormalizeNamingService;\n    }\n\n    public override async Task SaveAsync(BlobProviderSaveArgs args)\n    {\n        var blobName = AwsBlobNameCalculator.Calculate(args);\n        var configuration = args.Configuration.GetAwsConfiguration();\n        var containerName = GetContainerName(args);\n\n        using (var amazonS3Client = await GetAmazonS3Client(args))\n        {\n            if (!args.OverrideExisting && await BlobExistsAsync(amazonS3Client, containerName, blobName))\n            {\n                throw new BlobAlreadyExistsException(\n                    $\"Saving BLOB '{args.BlobName}' does already exists in the container '{containerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.\");\n            }\n\n            if (configuration.CreateContainerIfNotExists)\n            {\n                await CreateContainerIfNotExists(amazonS3Client, containerName);\n            }\n\n            if (!RequiresRetrySafeUpload(args))\n            {\n                await PutObjectAsync(amazonS3Client, containerName, blobName, args.BlobStream, configuration, args.CancellationToken);\n                return;\n            }\n\n            // The SDK can not retry the upload of a non-seekable stream (like an encrypting\n            // stream). A small source with a known length is buffered in memory and uploaded\n            // as a retryable PutObject; anything larger (or with an unknown length) goes\n            // through a TransferUtility multipart upload, which buffers and retries part by part","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/AwsBlobProvider.cs#L26-L62","documentation":"Thrown by AwsBlobProvider.SaveAsync when saving a blob with OverrideExisting=false while an object with the same calculated name already exists in the S3 bucket. It protects against unintended overwrites by calling BlobExistsAsync before any PutObject attempt. The exception is raised inside the using-block of the AmazonS3Client, before the upload path is chosen.","triggerScenarios":"Invoking SaveAsync on a blob container backed by the AWS provider where AwsBlobNameCalculator.Calculate yields a key that already exists in the bucket, with args.OverrideExisting set to its default (false). Triggers on retries of an upload that partially or fully succeeded.","commonSituations":"Stable deterministic keys (hashes, user IDs) re-saved on profile updates, race conditions between concurrent producers, retry of a de-duplicated upload after the first attempt completed server-side, or migration scripts that re-run.","solutions":["Pass overrideExisting: true when the new content should replace the existing object.","Use a unique key per save (GUID/version suffix) so collisions cannot occur.","Call ExistsAsync beforehand and branch on the result.","Delete the stale object before re-saving if overwrite semantics are not desired but the key must be reused."],"exampleFix":"// before\nawait container.SaveAsync(key, stream);\n\n// after\nawait container.SaveAsync(key, stream, overrideExisting: true);","handlingStrategy":"validation","validationCode":"if (await container.ExistsAsync(blobName))\n{\n    // existing key; choose overwrite, rename, or abort\n    await container.SaveAsync(blobName, stream, overrideExisting: true);\n    return;\n}\nawait container.SaveAsync(blobName, stream);","typeGuard":"bool willConflict = !args.OverrideExisting && await container.ExistsAsync(blobName);","tryCatchPattern":"try\n{\n    await container.SaveAsync(blobName, stream);\n}\ncatch (BlobAlreadyExistsException)\n{\n    await container.SaveAsync(blobName, stream, overrideExisting: true);\n}","preventionTips":["Set OverrideExisting on updates.","Use unique keys for append-only data.","Make save operations idempotent by keying on content hash when collisions must be avoided."],"tags":["blob-storage","aws","s3","save","conflict","abp"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}