Rails 7.1删除附件时Active Storage报Aws::S3::Errors::NoSuchKey错误求助
解决Rails 7.1 Active Storage搭配S3兼容存储时PurgeJob的NoSuchKey错误
问题场景
我在Rails 7.1应用中定义了带附件的User模型:
class User has_one_attached :avatar end
使用Active Storage搭配Scaleway的S3兼容存储服务时,创建和删除附件的功能正常——删除后对象存储中的文件已消失,数据库中ActiveStorage::Attachment.count统计也正确,但Sidekiq执行ActiveStorage::PurgeJob时会抛出Aws::S3::Errors::NoSuchKey错误,日志如下:
10:42:10 sidekiq.1 | I, [2024-01-04T10:42:10.084390 #7886] INFO -- : S3 Storage (116.8ms) Deleted file from key: s9jppxubel7hc96a6dulvcd0hy1g 10:42:10 sidekiq.1 | I, [2024-01-04T10:42:10.123300 #7886] INFO -- : S3 Storage (126.2ms) Deleted file from key: 9ye6w1rfcxufsbjkh58xdq79jugm 10:42:10 sidekiq.1 | I, [2024-01-04T10:42:10.186220 #7886] INFO -- : S3 Storage (62.7ms) Deleted files by key prefix: variants/9ye6w1rfcxufsbjkh58xdq79jugm/ 10:42:10 sidekiq.1 | E, [2024-01-04T10:42:10.186404 #7886] ERROR -- : Error performing ActiveStorage::PurgeJob (Job ID: 158ef8d0-0d3b-4438-b5f9-cfbbeed36561) from Sidekiq(default) in 199.24ms: Aws::S3::Errors::NoSuchKey (The specified key does not exist.):
经测试,DigitalOcean Spaces及纯净Rails 7.1.2应用均存在此问题,根源指向Active Storage的delete_prefixed方法。我的Active Storage配置如下:
scaleway: service: S3 access_key_id: <%= ENV.fetch("SCALEWAY_S3_ACCESS_KEY_ID") %> secret_access_key: <%= ENV.fetch("SCALEWAY_S3_ACCESS_KEY_SECRET") %> region: <%= ENV.fetch("SCALEWAY_S3_REGION") %> bucket: <%= ENV.fetch("SCALEWAY_S3_BUCKET_NAME") %> endpoint: <%= ENV.fetch("SCALEWAY_S3_ENDPOINT") %>
解决方法
问题核心是:部分S3兼容存储(如Scaleway、DigitalOcean Spaces)对不存在的前缀执行批量删除时会抛出NoSuchKey错误,而AWS原生S3会忽略该情况返回成功。我们可以通过重写Active Storage的S3服务类来捕获这个异常:
- 在
config/initializers目录下创建active_storage_s3_purge_fix.rb文件 - 添加以下代码:
require "active_storage/service/s3_service" class ActiveStorage::Service::S3Service def delete_prefixed(prefix) instrument :delete_prefixed, prefix: prefix do bucket.objects(prefix: prefix).batch_delete! rescue Aws::S3::Errors::NoSuchKey # 忽略不存在前缀的错误,避免Sidekiq报错 end end end
该代码会覆盖原生的delete_prefixed方法,当执行批量删除遇到NoSuchKey错误时直接忽略,不会影响实际的删除逻辑(因为文件已经被成功删除,只是变体前缀可能不存在)。
内容的提问来源于stack exchange,提问作者basiszwo
相关产品推荐
相关产品推荐

