Échec du téléchargement de la sauvegarde en raison d'un TransferManager non initialisé

Après la mise à jour vers v2026.8.0-latest.1 +4, mes sauvegardes ont commencé à échouer. Voici les journaux : log.txt.zip (22,1 Ko)

En particulier, voici la section qui semble pertinente :

[2026-08-04 03:37:52] Uploading archive...
[2026-08-04 03:37:52] EXCEPTION: uninitialized constant Aws::S3::TransferManager
[2026-08-04 03:37:52] /var/www/discourse/lib/s3_helper.rb:453:in 'S3Helper#transfer_manager'
/var/www/discourse/lib/s3_helper.rb:332:in 'S3Helper#upload_file'
/var/www/discourse/lib/backup_restore/s3_backup_store.rb:48:in 'BackupRestore::S3BackupStore#upload_file'
/var/www/discourse/lib/backup_restore/creator.rb:437:in 'BackupRestore::Creator#upload_archive'
/var/www/discourse/lib/backup_restore/creator.rb:41:in 'BackupRestore::Creator#run'
/var/www/discourse/lib/backup_restore.rb:13:in 'BackupRestore.backup!'
/var/www/discourse/app/jobs/regular/create_backup.rb:10:in 'Jobs::CreateBackup#execute'
/var/www/discourse/app/jobs/base.rb:313:in 'block (2 levels) in Jobs::Base#perform'

Je ne sais pas comment résoudre ce problème.

J’ai mis à jour vers v2026.9.0-latest +565, mais je rencontre toujours exactement le même problème.

La version de Discourse que vous exécutez inclut une version d’aws-sdk-s3 qui devrait fournir Aws::S3::TransferManager.

Utilisez-vous l’installation Docker officielle de Discourse ? Si vous utilisez la configuration Docker officielle, le conteneur a-t-il été entièrement reconstruit dans le cadre de la mise à niveau ?

Oui, je crois utiliser l’installation Docker officielle de Discourse. Existe-t-il un moyen d’en être certain ? Cela fait un moment que je n’ai pas effectué l’installation.

Pour mettre à jour, j’ai exécuté ./launcher rebuild app. Je suppose que cela signifie que le conteneur a été entièrement reconstruit, mais je me trompe peut-être ?

Quelques détails supplémentaires qui pourraient être pertinents :

  • Exécution sur Ubuntu 24.04.4 LTS
  • app.yml installe les plugins officiels docker_manager et discourse-doc-categories dans le hook after_code. Aucun autre plugin n’est défini dans app.yml.
  • J’essaie de stocker les sauvegardes sur un stockage compatible S3 fourni par Backblaze, et cela fonctionnait auparavant.

Une chose qui pourrait aider à préciser le problème est de vérifier quelle version du gem aws-sdk-s3 est réellement chargée dans le conteneur en cours d’exécution.

La modification de Discourse qui a introduit Aws::S3::TransferManager a également fait passer aws-sdk-s3 de la version 1.182.0 à la 1.227.0 :

À la révision de Discourse que vous avez liée, le fichier Gemfile.lock devrait toujours utiliser aws-sdk-s3 1.227.0, qui fournit bien Aws::S3::TransferManager.

Pourriez-vous essayer d’accéder au conteneur :

cd /var/discourse
./launcher enter app

Ensuite, à l’intérieur du conteneur :

cd /var/www/discourse
bundle info aws-sdk-s3
bundle exec ruby -e '
require "aws-sdk-s3"
puts "gem: #{Gem.loaded_specs["aws-sdk-s3"]&.full_name}"
puts "path: #{Gem.loaded_specs["aws-sdk-s3"]&.full_gem_path}"
p Aws::S3.autoload?(:TransferManager)
p Aws::S3::TransferManager
'

Il peut également être utile de vérifier l’application elle-même sous Rails :

RAILS_ENV=production bundle exec rails runner '
puts "aws-sdk-s3: #{Gem.loaded_specs["aws-sdk-s3"]&.version}"
p Aws::S3.autoload?(:TransferManager)
p Aws::S3::TransferManager
'

Ensuite, quittez le conteneur avec :

logout

Si cela signale une version plus ancienne de aws-sdk-s3, ou si TransferManager est absent, cela expliquerait l’exception lors de la sauvegarde et suggérerait que les gems installées dans le conteneur ne correspondent pas au Gemfile.lock actuel de Discourse.

Si la version 1.227.0 est signalée et que Aws::S3::TransferManager est résolu avec succès, alors le problème est plus inhabituel et nous saurons qu’il faut examiner ce qui diffère entre le processus de sauvegarde Sidekiq et cet environnement interactif.

Puisque vous utilisez ./launcher rebuild app, cela ressemble bien au flux de travail standard de discourse_docker ; les commandes ci-dessus nous permettront de savoir plus précisément ce qui a effectivement atterri dans le conteneur reconstruit.

Il semble que j’ai une ancienne version d’aws-sdk-s3.

$ bundle info aws-sdk-s3
  * aws-sdk-s3 (1.177.0)
	Summary: AWS SDK for Ruby - Amazon S3
	Homepage: https://github.com/aws/aws-sdk-ruby
	Source Code: https://github.com/aws/aws-sdk-ruby/tree/version-3/gems/aws-sdk-s3
	Changelog: https://github.com/aws/aws-sdk-ruby/tree/version-3/gems/aws-sdk-s3/CHANGELOG.md
	Path: /var/www/discourse/vendor/bundle/ruby/3.4.0/gems/aws-sdk-s3-1.177.0

En cherchant à comprendre, je me suis rappelé que j’avais utilisé ce contournement pour résoudre un problème lié à l’incompatibilité de l’AWS SDK avec Backblaze. En me remémorant le sujet, il semble que Backblaze ait mis à jour son API, ce qui rend le contournement inutile.

Après avoir retiré le contournement, la sauvegarde a réussi ! Merci pour votre aide. :heart:

Une réflexion à ce sujet : des modèles de compatibilité temporaire comme celui-ci seraient peut-être plus sûrs s’ils étaient dotés d’une condition d’auto-expiration ou de garde-fou, plutôt que de continuer à écraser indéfiniment les dépendances de Discourse.

Par exemple, pour les rétroportages de code source temporaires, je prévois d’utiliser des hooks en production qui vérifient d’abord si le correctif amont est déjà présent, et n’appliquent le correctif que s’il est encore nécessaire.

Dans ce cas, une logique de ce type aurait potentiellement pu empêcher le maintien de l’épinglage de aws-sdk-s3 1.177.0 une fois que Discourse lui-même a commencé à dépendre de fonctionnalités plus récentes du SDK :

hooks:
  after_bundle_exec:
    - exec:
        cd: $home
        cmd:
          - |
            if grep -q "Aws::S3::TransferManager" lib/s3_helper.rb; then
              echo "Discourse nécessite désormais Aws::S3::TransferManager ; on saute le downgrade obsolète de aws-sdk-s3 pour Backblaze"
            else
              echo "Application de l'épinglage temporaire de compatibilité aws-sdk-s3 pour Backblaze"
              bundle config set frozen false
              sed -i 's/gem "aws-sdk-s3", require: false/gem "aws-sdk-s3", "1.177.0", require: false/' Gemfile
              bundle update aws-sdk-s3
              bundle add aws-sdk-core --version 3.215
            fi

Cette vérification particulière n’est qu’illustrative — une vérification de version plus générale ou un échec explicite lorsque Discourse dépasse la version de SDK attendue serait probablement préférable.

Même un échec bruyant serait probablement préférable à la production silencieuse d’un conteneur dont les gems ne correspondent plus aux versions attendues par Discourse.

Bien que je convienne qu’il aurait été souhaitable que l’erreur soit signalée de manière explicite, il se trouve que je voulais que les gem ne correspondent pas aux versions attendues par Discourse, car la version plus récente de aws-sdk-s3 envoyait des en-têtes que Backblaze ne prenait pas en charge, et je voulais que les sauvegardes fonctionnent.

Je ne sais pas s’il existait un contrôle que j’aurais pu mettre en place proactivement à l’avance pour m’avertir lorsque le contournement ne serait plus nécessaire. J’ai mis en œuvre ce contournement il y a un an et demi, en avril 2025, avant qu’un correctif ne soit disponible.

Je pense que le mieux que j’aurais pu faire était d’ajouter une date d’expiration, afin de m’obliger à vérifier si le contournement était toujours nécessaire. Une fonctionnalité de ce type pourrait être utile. Ou peut-être que c’est à moi d’être plus proactif et de programmer des rappels pour vérifier si le contournement est toujours nécessaire. Avoir quelques notes m’a aidé à cet égard.