Db:seed_fu schlägt bei 002_groups.rb während des Upgrades fehl: Validierung fehlgeschlagen: Name wurde bereits verwendet

Beim Upgrade von v2026.3.0-latest ist ein Problem aufgetreten. Der Task rake db:seed_fu schlägt beim Ausführen von 002_groups.rb mit folgendem Fehler fehl:

ActiveRecord::RecordInvalid: Validation failed: Name has already been taken. (ActiveRecord::RecordInvalid)

Der Absturz erfolgt genau dann, wenn der Seeder versucht, die neuen Systemgruppen zu initialisieren (ID 4: anonymous und ID 5: logged_in_users).

Über die Rails-Konsole bestätigt: Ein manueller Check schlägt bei der Validierung fehl, aber das Umgehen der Validierung ermöglicht das Speichern des Datensatzes ohne Probleme:

# Dies schlägt mit „Name has already been taken“ fehl
g = Group.new(id: 4, name: „anonymous“, automatic: true)
g.valid?

# Dies funktioniert einwandfrei und beweist, dass es keinen tatsächlichen Konflikt gibt
g.save(validate: false)

Ich konnte diese Hürde überwinden, indem ich diese neuen Systemgruppen manuell erstellt habe:

ActiveRecord::Base.transaction do
  g4 = Group.new(id: 4, name: "anonymous", automatic: true)
  g4.save(validate: false)

  g5 = Group.new(id: 5, name: "logged_in_users", automatic: true)
  g5.save(validate: false)
end

Nun läuft rake db:seed_fu ohne Fehler durch.

Vollständiger Stacktrace:

# rake --trace db:seed_fu
** Invoke db:seed_fu (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:seed_fu

== Seed from /var/www/discourse/db/fixtures/001_refresh.rb

== Seed from /var/www/discourse/db/fixtures/002_groups.rb
rake aborted!
ActiveRecord::RecordInvalid: Validation failed: Name has already been taken (ActiveRecord::RecordInvalid)
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/validations.rb:87:in 'ActiveRecord::Validations#raise_validation_error'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/validations.rb:54:in 'ActiveRecord::Validations#save!'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/transactions.rb:365:in 'block in ActiveRecord::Transactions#save!'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/transactions.rb:417:in 'block (2 levels) in ActiveRecord::Transactions#with_transaction_returning_status'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:357:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/transactions.rb:413:in 'block in ActiveRecord::Transactions#with_transaction_returning_status'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:416:in 'ActiveRecord::ConnectionAdapters::ConnectionPool#with_connection'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_handling.rb:312:in 'ActiveRecord::ConnectionHandling#with_connection'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/transactions.rb:409:in 'ActiveRecord::Transactions#with_transaction_returning_status'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/transactions.rb:365:in 'ActiveRecord::Transactions#save!'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/suppressor.rb:56:in 'ActiveRecord::Suppressor#save!'
/var/www/discourse/app/models/group.rb:539:in 'Group.refresh_automatic_group!'
/var/www/discourse/app/models/group.rb:719:in 'block in Group.ensure_automatic_groups!'
/var/www/discourse/app/models/group.rb:719:in 'Hash#each_key'
/var/www/discourse/app/models/group.rb:719:in 'Group.ensure_automatic_groups!'
(eval at /var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:46):3:in 'block (2 levels) in SeedFu::Runner#run_file'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:46:in 'Kernel#eval'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:46:in 'block (2 levels) in SeedFu::Runner#run_file'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:58:in 'block in SeedFu::Runner#open'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:57:in 'IO.open'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:57:in 'SeedFu::Runner#open'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:36:in 'block in SeedFu::Runner#run_file'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/transaction.rb:626:in 'block in ActiveRecord::ConnectionAdapters::TransactionManager#within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/concurrency/null_lock.rb:9:in 'ActiveSupport::Concurrency::NullLock#synchronize'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/transaction.rb:623:in 'ActiveRecord::ConnectionAdapters::TransactionManager#within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:367:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:359:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/transactions.rb:233:in 'block in ActiveRecord::Transactions::ClassMethods#transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:416:in 'ActiveRecord::ConnectionAdapters::ConnectionPool#with_connection'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_handling.rb:312:in 'ActiveRecord::ConnectionHandling#with_connection'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/transactions.rb:232:in 'ActiveRecord::Transactions::ClassMethods#transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:35:in 'SeedFu::Runner#run_file'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:26:in 'block in SeedFu::Runner#run'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:25:in 'Array#each'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/seed-fu/runner.rb:25:in 'SeedFu::Runner#run'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/discourse-seed-fu.rb:29:in 'SeedFu.seed'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/discourse-seed-fu-2.3.12/lib/tasks/seed_fu.rake:36:in 'block (2 levels) in <main>'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb:281:in 'block in Rake::Task#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb:281:in 'Array#each'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb:281:in 'Rake::Task#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb:219:in 'block in Rake::Task#invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb:199:in 'Monitor#synchronize'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb:199:in 'Rake::Task#invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb:188:in 'Rake::Task#invoke'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb:183:in 'Rake::Application#invoke_task'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb:139:in 'block (2 levels) in Rake::Application#top_level'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb:139:in 'Array#each'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb:139:in 'block in Rake::Application#top_level'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb:148:in 'Rake::Application#run_with_threads'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb:133:in 'Rake::Application#top_level'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb:84:in 'block in Rake::Application#run'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb:209:in 'Rake::Application#standard_exception_handling'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb:81:in 'Rake::Application#run'
bin/rake:13:in '<top (required)>'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/cli/exec.rb:59:in 'Kernel.load'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/cli/exec.rb:59:in 'Bundler::CLI::Exec#kernel_load'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/cli/exec.rb:23:in 'Bundler::CLI::Exec#run'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/cli.rb:452:in 'Bundler::CLI#exec'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/vendor/thor/lib/thor/command.rb:28:in 'Bundler::Thor::Command#run'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in 'Bundler::Thor::Invocation#invoke_command'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/vendor/thor/lib/thor.rb:538:in 'Bundler::Thor.dispatch'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/cli.rb:35:in 'Bundler::CLI.dispatch'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/vendor/thor/lib/thor/base.rb:584:in 'Bundler::Thor::Base::ClassMethods#start'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/cli.rb:29:in 'Bundler::CLI.start'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/exe/bundle:28:in 'block in <top (required)>'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/lib/bundler/friendly_errors.rb:117:in 'Bundler.with_friendly_errors'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/bundler-2.6.4/exe/bundle:20:in '<top (required)>'
/usr/local/bin/bundle:25:in 'Kernel#load'
/usr/local/bin/bundle:25:in '<main>'
Tasks: TOP => db:seed_fu
2 „Gefällt mir“

*Wo ist der „Ich auch!

2 „Gefällt mir“

Ich schaue mir das an.

Es gibt eine Migration, die diesen Namenskonflikt behandelt, daher bin ich mir nicht sicher, warum es im Fall des OP nicht funktioniert:

Führen Sie dies separat aus, bevor Sie die Migrationen durchführen?

Ihre Migration prüft vorhandene Gruppen. Sie sollte jedoch auch vorhandene Benutzer prüfen, da Benutzer und Gruppen denselben Namensraum verwenden und Sie keine Gruppe mit demselben Namen wie ein Benutzer erstellen können.

Hmm, okay, das ist ziemlich nervig… Ich mache gerade einen PR, um das zu beheben:

Was, wie du sagst, die Wahrscheinlichkeit einer Kollision drastisch reduzieren sollte. Ich bezweifle sehr, dass es einen Benutzer namens anonymous_users gibt, daher denke ich, dass keine automatisierte Prüfung oder Migration erforderlich ist, wenn ich diesen Umbenennungsvorgang durchführe.

1 „Gefällt mir“

Okay, das sollte den Haken machen. Es behebt auch einige Probleme mit der Logik für die bevorstehende Änderung für https://meta.discourse.org/t/granular-group-based-permissions-for-anonymous-and-logged-in-users/402273:

https://github.com/discourse/discourse/pull/40435

2 „Gefällt mir“

Anfangs nicht. Es schlug während des normalen Neuaufbauprozesses bei den Migrationen fehl, wodurch es mir zunächst aufgefallen ist, und ich habe es dann lokalisiert. Anschließend habe ich die Rake-Aufgabe manuell zur Fehleranalyse ausgeführt.

2 „Gefällt mir“

Alles klar, ich habe den PR jetzt gemergt. Das sollte die Namenskonflikte beheben.