L'exportation de l'archive des données utilisateur échoue : méthode 'url' non définie pour une instance de DiscourseDataExplorer::QueryGroup

Divers : J’ai utilisé ask.discourse pour rédiger ce rapport de bug après une conversation. De plus, je sais que je suis en retard sur les mises à jour, mais je voulais publier cela tant que c’était encore frais dans ma mémoire.

J’ai pu reproduire le problème sur deux comptes d’utilisateurs différents.

Résumé

La demande d’une archive des données utilisateur (Préférences → Exporter vos données → Demander l’archive) échoue pour les utilisateurs qui ont mis un rapport de groupe Data Explorer en signet. Le travail en arrière-plan Jobs::ExportUserArchive plante lors de la génération du CSV des signets, si bien que l’exportation ne se termine jamais et qu’aucun lien de téléchargement n’est envoyé.

Environnement

  • Version de Discourse : 2026.8.0-latest.1
  • Data Explorer : inclus dans le cœur (la version suit celle du cœur)
  • Auto-hébergé / hébergé : auto-hébergé
  • Stack Ruby/Rails selon la trace d’erreur : activemodel/activerecord 8.0.5.1, Sidekiq 7.3.10

Étapes pour reproduire

  1. En tant qu’administrateur, créez une requête Data Explorer et accordez l’accès à un groupe.
  2. Sur l’onglet Rapports du groupe, cliquez sur Signet sur la requête pour qu’elle devienne un rapport de groupe en signet.
  3. En tant que cet même utilisateur, allez dans Préférences → Exporter vos données → Demander l’archive.
  4. Observez l’échec du travail (vérifiez Admin → Journaux ou les journaux Sidekiq).

Comportement attendu

L’archive utilisateur devrait être générée et l’utilisateur devrait recevoir le lien de téléchargement, y compris ses signets.

Comportement réel

Le travail d’exportation lève une exception et l’archive échoue. La trace d’erreur montre que le plantage se produit dans bookmarks_export, où le travail appelle .url sur l’objet en signet :

Job exception: undefined method 'url' for an instance of DiscourseDataExplorer::QueryGroup

Trace d’erreur (réduite aux cadres pertinents) :

activemodel-8.0.5.1/lib/active_model/attribute_methods.rb:512:in 'ActiveModel::AttributeMethods#method_missing'
activerecord-8.0.5.1/lib/active_record/attribute_methods.rb:495:in 'ActiveRecord::AttributeMethods#method_missing'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:325:in 'block in Jobs::ExportUserArchive#bookmarks_export'
activerecord-8.0.5.1/lib/active_record/relation/delegation.rb:101:in 'Array#each'
activerecord-8.0.5.1/lib/active_record/relation/delegation.rb:101:in 'ActiveRecord::Delegation#each'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:319:in 'Jobs::ExportUserArchive#bookmarks_export'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:170:in 'Kernel#public_send'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:170:in 'block (2 levels) in Jobs::ExportUserArchive#execute'
/var/www/discourse/app/jobs/regular/export_user_archive.rb:168:in 'block in Jobs::ExportUserArchive#execute'

Analyse

Les signets sont polymorphes. Le travail d’exportation appelle bookmarkable.url, ce qui fonctionne pour les types de signets du cœur (Topic, Post), mais DiscourseDataExplorer::QueryGroup n’implémente pas url, si bien que le travail lève NoMethodError sur le premier signet de ce type.

Il semble que Data Explorer enregistre les groupes de requêtes comme étant signetables (via le bouton Signet du rapport de groupe), mais le modèle manque de la méthode url (ou le travail d’exportation du cœur a besoin d’une garde pour les types de signetables qui n’en fournissent pas).

Correction suggérée

Soit implémenter une méthode url sur DiscourseDataExplorer::QueryGroup, soit rendre bookmarks_export du cœur défensif (par exemple, bookmarkable.respond_to?(:url) / rescue par ligne) afin qu’un seul type de signetable non pris en charge ne puisse pas faire échouer toute l’exportation.

Contournement

Supprimer les signets fautifs (lignes dans bookmarks où bookmarkable_type = 'DiscourseDataExplorer::QueryGroup' pour l’utilisateur concerné) permet à l’exportation de se terminer.