{"record":{"id":"4119585ea3bc09a5","repo":"abpframework/abp","slug":"saving-blob-args-blobname-does-already-exists","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.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs","lineNumber":45,"sourceCode":"        var aliyunConfig = blobContainerConfiguration.GetAliyunConfiguration();\n        return OssClientFactory.Create(aliyunConfig);\n    }\n\n    protected virtual IOss GetOssClient(AliyunBlobProviderConfiguration aliyunConfig)\n    {\n        return OssClientFactory.Create(aliyunConfig);\n    }\n\n\n    public override Task SaveAsync(BlobProviderSaveArgs args)\n    {\n        var containerName = GetContainerName(args);\n        var blobName = AliyunBlobNameCalculator.Calculate(args);\n        var aliyunConfig = args.Configuration.GetAliyunConfiguration();\n        var ossClient = GetOssClient(aliyunConfig);\n        if (!args.OverrideExisting && BlobExists(ossClient, containerName, blobName))\n        {\n            throw new BlobAlreadyExistsException($\"Saving BLOB '{args.BlobName}' does already exists in the container '{containerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.\");\n        }\n        if (aliyunConfig.CreateContainerIfNotExists)\n        {\n            if (!ossClient.DoesBucketExist(containerName))\n            {\n                ossClient.CreateBucket(containerName);\n            }\n        }\n        ossClient.PutObject(containerName, blobName, args.BlobStream);\n        return Task.CompletedTask;\n    }\n\n    public override Task<bool> DeleteAsync(BlobProviderDeleteArgs args)\n    {\n        var containerName = GetContainerName(args);\n        var blobName = AliyunBlobNameCalculator.Calculate(args);\n        var ossClient = GetOssClient(args.Configuration);\n        if (!BlobExists(ossClient, containerName, blobName))","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs#L27-L63","documentation":"Thrown by AliyunBlobProvider.SaveAsync when a blob is saved without OverrideExisting=true and an object with the same (calculated) blob name already exists in the OSS bucket. It is a data-integrity guard preventing accidental silent overwrites of existing stored objects. The check first confirms the bucket exists (DoesBucketExist) and then that the object exists (DoesObjectExist) before PutObject is ever called.","triggerScenarios":"Calling IBlobContainer.SaveAsync (or the underlying BlobProvider SaveAsync) for a blobName whose AliyunBlobNameCalculator.Calculate result already maps to an existing OSS object, while args.OverrideExisting is false (the default). Also triggered by re-saving after a previous successful PutObject under the same name.","commonSituations":"Re-uploading an avatar or document whose key is stable (e.g. user-id based), replaying an upload after a transient error that actually completed server-side, or multiple concurrent writers racing to create the same key. Also when a previous run left the object in place and the retry did not set OverrideExisting.","solutions":["If overwriting is intended, pass overrideExisting: true to the SaveAsync call so the existence check is skipped.","If the object is stale, delete it first (DeleteAsync) or confirm it should not be recreated.","Generate a unique blob name (e.g. append a GUID or timestamp) when each upload must create a distinct object.","Before saving, call ExistsAsync to branch your logic instead of relying on the throw."],"exampleFix":"// before\nawait container.SaveAsync(\"profile.png\", stream);\n\n// after (overwrite is desired)\nawait container.SaveAsync(\"profile.png\", stream, overrideExisting: true);\n\n// after (unique per upload)\nawait container.SaveAsync($\"profile-{Guid.NewGuid():N}.png\", stream);","handlingStrategy":"validation","validationCode":"// Check existence before saving when overwrite is not desired\nif (await container.ExistsAsync(blobName))\n{\n    // decide: skip, rename, or explicitly overwrite\n    return;\n}\nawait container.SaveAsync(blobName, stream);","typeGuard":"if (!args.OverrideExisting && await container.ExistsAsync(blobName)) { /* will throw on save */ }","tryCatchPattern":"try\n{\n    await container.SaveAsync(blobName, stream);\n}\ncatch (BlobAlreadyExistsException ex)\n{\n    // handle: rename key, prompt user, or retry with overrideExisting: true\n}","preventionTips":["Pass overrideExisting: true whenever the save is an update of existing content.","Use globally unique blob names (GUID/timestamp) for immutable append-style uploads.","For retries, verify whether the previous attempt completed before re-saving."],"tags":["blob-storage","aliyun","oss","save","conflict","abp"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}