Bootstrap error: relation "ai_agent_mcp_servers" does not exist -- due to migration id collision

Bootstrap is failing with this error:

PG::UndefinedTable: ERROR:  relation "ai_agent_mcp_servers" does not exist

more stuff:

in /etc/nginx/conf.d/discourse.conf
I, [2026-03-30T15:32:25.835970 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'LOAD_PLUGINS=0 bundle exec rake plugin:pull_compatible_all'
discourse-citationwizard is already at latest compatible version
discourse-prometheus is already at latest compatible version
I, [2026-03-30T15:32:33.549352 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
gem install prometheus_exporter -v 2.2.0 -i /var/www/discourse/plugins/discourse-prometheus/gems/3.4.7 --no-document --ignore-dependencies --no-user-install
Successfully installed prometheus_exporter-2.2.0
1 gem installed
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled: (StandardError)

PG::UndefinedTable: ERROR:  relation "ai_agent_mcp_servers" does not exist
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in 'PG::Connection#exec'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in 'PG::Connection#async_exec'
(eval at /var/www/discourse/lib/method_profiler.rb:38):24:in 'PG::Connection#async_exec'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:167:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#perform_query'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:556:in 'block (2 levels) in ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:1022:in 'block in ActiveRecord::ConnectionAdapters::AbstractAdapter#with_raw_connection'
/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_adapter.rb:991:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#with_raw_connection'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:555:in 'block in ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/notifications/instrumenter.rb:58:in 'ActiveSupport::Notifications::Instrumenter#instrument'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:1142:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#log'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:554:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:591:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#internal_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:137:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/query_cache.rb:27:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:40:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/schema_statements.rb:643:in 'ActiveRecord::ConnectionAdapters::SchemaStatements#add_column'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/postgresql/schema_statements.rb:462:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements#add_column'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration/default_strategy.rb:10:in 'ActiveRecord::Migration::DefaultStrategy#method_missing'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1055:in 'block in ActiveRecord::Migration#method_missing'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1021:in 'block in ActiveRecord::Migration#say_with_time'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/benchmark.rb:17:in 'ActiveSupport::Benchmark.realtime'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1021:in 'ActiveRecord::Migration#say_with_time'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1044:in 'ActiveRecord::Migration#method_missing'
/var/www/discourse/plugins/discourse-ai/db/migrate/20260319070000_add_selected_tool_names_to_ai_agent_mcp_servers.rb:5:in 'AddSelectedToolNamesToAiAgentMcpServers#change'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:990:in 'ActiveRecord::Migration#exec_migration'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in 'block in FreedomPatches::SchemaMigrationDetails#exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/benchmark-0.5.0/lib/benchmark.rb:305:in 'Benchmark.measure'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in 'FreedomPatches::SchemaMigrationDetails#exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:974:in 'block (2 levels) in ActiveRecord::Migration#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/benchmark.rb:17:in 'ActiveSupport::Benchmark.realtime'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:973:in 'block in ActiveRecord::Migration#migrate'
/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/migration.rb:972:in 'ActiveRecord::Migration#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1186:in 'ActiveRecord::MigrationProxy#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1535:in 'block in ActiveRecord::Migrator#execute_migration_in_transaction'
/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/migration.rb:1586:in 'ActiveRecord::Migrator#ddl_transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1534:in 'ActiveRecord::Migrator#execute_migration_in_transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1508:in 'Array#each'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1508:in 'ActiveRecord::Migrator#migrate_without_lock'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1453:in 'block in ActiveRecord::Migrator#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1606:in 'ActiveRecord::Migrator#with_advisory_lock'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1453:in 'ActiveRecord::Migrator#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1260:in 'ActiveRecord::MigrationContext#up'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1235:in 'ActiveRecord::MigrationContext#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/tasks/database_tasks.rb:270:in 'ActiveRecord::Tasks::DatabaseTasks#migrate'
/var/www/discourse/lib/tasks/db.rake:267:in 'block (2 levels) in <main>'
/var/www/discourse/lib/distributed_mutex.rb:53:in 'block in DistributedMutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in 'Thread::Mutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in 'DistributedMutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in 'DistributedMutex.synchronize'
/var/www/discourse/lib/tasks/db.rake:242:in 'block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.3.1/exe/rake:27:in '<top (required)>'
/usr/local/bin/bundle:25:in 'Kernel#load'
/usr/local/bin/bundle:25:in '<main>'

Caused by:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation "ai_agent_mcp_servers" does not exist (ActiveRecord::StatementInvalid)
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in 'PG::Connection#exec'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in 'PG::Connection#async_exec'
(eval at /var/www/discourse/lib/method_profiler.rb:38):24:in 'PG::Connection#async_exec'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:167:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#perform_query'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:556:in 'block (2 levels) in ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:1022:in 'block in ActiveRecord::ConnectionAdapters::AbstractAdapter#with_raw_connection'
/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_adapter.rb:991:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#with_raw_connection'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:555:in 'block in ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/notifications/instrumenter.rb:58:in 'ActiveSupport::Notifications::Instrumenter#instrument'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:1142:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#log'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:554:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:591:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#internal_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:137:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/query_cache.rb:27:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:40:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/schema_statements.rb:643:in 'ActiveRecord::ConnectionAdapters::SchemaStatements#add_column'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/postgresql/schema_statements.rb:462:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements#add_column'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration/default_strategy.rb:10:in 'ActiveRecord::Migration::DefaultStrategy#method_missing'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1055:in 'block in ActiveRecord::Migration#method_missing'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1021:in 'block in ActiveRecord::Migration#say_with_time'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/benchmark.rb:17:in 'ActiveSupport::Benchmark.realtime'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1021:in 'ActiveRecord::Migration#say_with_time'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1044:in 'ActiveRecord::Migration#method_missing'
/var/www/discourse/plugins/discourse-ai/db/migrate/20260319070000_add_selected_tool_names_to_ai_agent_mcp_servers.rb:5:in 'AddSelectedToolNamesToAiAgentMcpServers#change'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:990:in 'ActiveRecord::Migration#exec_migration'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in 'block in FreedomPatches::SchemaMigrationDetails#exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/benchmark-0.5.0/lib/benchmark.rb:305:in 'Benchmark.measure'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in 'FreedomPatches::SchemaMigrationDetails#exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:974:in 'block (2 levels) in ActiveRecord::Migration#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/benchmark.rb:17:in 'ActiveSupport::Benchmark.realtime'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:973:in 'block in ActiveRecord::Migration#migrate'
/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/migration.rb:972:in 'ActiveRecord::Migration#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1186:in 'ActiveRecord::MigrationProxy#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1535:in 'block in ActiveRecord::Migrator#execute_migration_in_transaction'
/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/migration.rb:1586:in 'ActiveRecord::Migrator#ddl_transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1534:in 'ActiveRecord::Migrator#execute_migration_in_transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1508:in 'Array#each'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1508:in 'ActiveRecord::Migrator#migrate_without_lock'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1453:in 'block in ActiveRecord::Migrator#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1606:in 'ActiveRecord::Migrator#with_advisory_lock'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1453:in 'ActiveRecord::Migrator#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1260:in 'ActiveRecord::MigrationContext#up'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1235:in 'ActiveRecord::MigrationContext#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/tasks/database_tasks.rb:270:in 'ActiveRecord::Tasks::DatabaseTasks#migrate'
/var/www/discourse/lib/tasks/db.rake:267:in 'block (2 levels) in <main>'
/var/www/discourse/lib/distributed_mutex.rb:53:in 'block in DistributedMutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in 'Thread::Mutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in 'DistributedMutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in 'DistributedMutex.synchronize'
/var/www/discourse/lib/tasks/db.rake:242:in 'block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.3.1/exe/rake:27:in '<top (required)>'
/usr/local/bin/bundle:25:in 'Kernel#load'
/usr/local/bin/bundle:25:in '<main>'

Caused by:
PG::UndefinedTable: ERROR:  relation "ai_agent_mcp_servers" does not exist (PG::UndefinedTable)
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in 'PG::Connection#exec'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in 'PG::Connection#async_exec'
(eval at /var/www/discourse/lib/method_profiler.rb:38):24:in 'PG::Connection#async_exec'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:167:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#perform_query'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:556:in 'block (2 levels) in ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:1022:in 'block in ActiveRecord::ConnectionAdapters::AbstractAdapter#with_raw_connection'
/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_adapter.rb:991:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#with_raw_connection'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:555:in 'block in ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/notifications/instrumenter.rb:58:in 'ActiveSupport::Notifications::Instrumenter#instrument'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:1142:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#log'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:554:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:591:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#internal_execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:137:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/query_cache.rb:27:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:40:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#execute'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/abstract/schema_statements.rb:643:in 'ActiveRecord::ConnectionAdapters::SchemaStatements#add_column'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/connection_adapters/postgresql/schema_statements.rb:462:in 'ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements#add_column'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration/default_strategy.rb:10:in 'ActiveRecord::Migration::DefaultStrategy#method_missing'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1055:in 'block in ActiveRecord::Migration#method_missing'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1021:in 'block in ActiveRecord::Migration#say_with_time'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/benchmark.rb:17:in 'ActiveSupport::Benchmark.realtime'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1021:in 'ActiveRecord::Migration#say_with_time'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1044:in 'ActiveRecord::Migration#method_missing'
/var/www/discourse/plugins/discourse-ai/db/migrate/20260319070000_add_selected_tool_names_to_ai_agent_mcp_servers.rb:5:in 'AddSelectedToolNamesToAiAgentMcpServers#change'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:990:in 'ActiveRecord::Migration#exec_migration'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in 'block in FreedomPatches::SchemaMigrationDetails#exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/benchmark-0.5.0/lib/benchmark.rb:305:in 'Benchmark.measure'
/var/www/discourse/lib/freedom_patches/schema_migration_details.rb:8:in 'FreedomPatches::SchemaMigrationDetails#exec_migration'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:974:in 'block (2 levels) in ActiveRecord::Migration#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.5/lib/active_support/benchmark.rb:17:in 'ActiveSupport::Benchmark.realtime'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:973:in 'block in ActiveRecord::Migration#migrate'
/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/migration.rb:972:in 'ActiveRecord::Migration#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1186:in 'ActiveRecord::MigrationProxy#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1535:in 'block in ActiveRecord::Migrator#execute_migration_in_transaction'
/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/migration.rb:1586:in 'ActiveRecord::Migrator#ddl_transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1534:in 'ActiveRecord::Migrator#execute_migration_in_transaction'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1508:in 'Array#each'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1508:in 'ActiveRecord::Migrator#migrate_without_lock'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1453:in 'block in ActiveRecord::Migrator#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1606:in 'ActiveRecord::Migrator#with_advisory_lock'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1453:in 'ActiveRecord::Migrator#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1260:in 'ActiveRecord::MigrationContext#up'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/migration.rb:1235:in 'ActiveRecord::MigrationContext#migrate'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.5/lib/active_record/tasks/database_tasks.rb:270:in 'ActiveRecord::Tasks::DatabaseTasks#migrate'
/var/www/discourse/lib/tasks/db.rake:267:in 'block (2 levels) in <main>'
/var/www/discourse/lib/distributed_mutex.rb:53:in 'block in DistributedMutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in 'Thread::Mutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in 'DistributedMutex#synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in 'DistributedMutex.synchronize'
/var/www/discourse/lib/tasks/db.rake:242:in 'block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/rake-13.3.1/exe/rake:27:in '<top (required)>'
/usr/local/bin/bundle:25:in 'Kernel#load'
/usr/local/bin/bundle:25:in '<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
== 20260319070000 AddSelectedToolNamesToAiAgentMcpServers: migrating ==========

So, here comes a bug report that ask.discourse.com wrote, but first, I want to share this bit that it offered:

I decided to let it be itself, and not “blunt and short”. :rofl: (I didn’t roll on the floor, but I did, truly, laugh out loud.

This seems like a credible report and likely better than I’d have written.

Bug report from ask . . .

Here’s a concise bug report you can post on Meta:

After updating, bootstrap fails during `db:migrate` with:

```text
PG::UndefinedTable: ERROR:  relation "ai_agent_mcp_servers" does not exist

The failing migration is:

/plugins/discourse-ai/db/migrate/20260319070000_add_selected_tool_names_to_ai_agent_mcp_servers.rb

It appears this migration tries to add a column to ai_agent_mcp_servers before that table exists.

Relevant part of the log:

== 20260319070000 AddSelectedToolNamesToAiAgentMcpServers: migrating ==========
PG::UndefinedTable: ERROR:  relation "ai_agent_mcp_servers" does not exist
...
/var/www/discourse/plugins/discourse-ai/db/migrate/20260319070000_add_selected_tool_names_to_ai_agent_mcp_servers.rb:5

This looks like a migration ordering issue in discourse-ai, or a missing earlier migration that should create ai_agent_mcp_servers.

Environment:

  • official Docker install
  • bootstrap fails on bundle exec rake db:migrate
  • plugins shown in logs include discourse-citationwizard and discourse-prometheus

Full report / logs:
Bootstrap error: relation “ai_agent_mcp_servers” does not exist

I had to know what I would sound like. . . .

Sure — here’s a more pfaffman-style version:

This looks like a `discourse-ai` migration bug.

Bootstrap dies in:

```text
/plugins/discourse-ai/db/migrate/20260319070000_add_selected_tool_names_to_ai_agent_mcp_servers.rb

with:

PG::UndefinedTable: ERROR:  relation "ai_agent_mcp_servers" does not exist

So that migration is trying to alter a table that hasn’t been created.

Relevant log:

== 20260319070000 AddSelectedToolNamesToAiAgentMcpServers: migrating ==========
PG::UndefinedTable: ERROR:  relation "ai_agent_mcp_servers" does not exist
...
/var/www/discourse/plugins/discourse-ai/db/migrate/20260319070000_add_selected_tool_names_to_ai_agent_mcp_servers.rb:5

Seems like either:

  • migration order is wrong, or
  • the migration that creates ai_agent_mcp_servers is missing / not being picked up.

Original report and full logs:
Bootstrap error: relation “ai_agent_mcp_servers” does not exist


If you want, I can also make it even more terse/snarky.

These appear to be in the correct order…

Do you see any evidence in the logs that the first one was run?

(FWIW, I prefer your original human-authored report in the OP. It sticks to the facts, and doesn’t reach for potentially-incorrect conclusions)

1 Like

Aha. Here’s what happened. It seems to be because we both used AI and it’s stupid and lazy. An alternative explanation is that it’s bad luck, but it looks like Claude (that’s what I used) doesn’t get a timestamp (NOT COOL, Claude), but just a date stamp and then adds a counter, so we both were working on the same day.

Here are the last few migrations that ran:

   up     20260316000001  Create discourse citationwizard openalex api keys
   up     20260316000002  Create discourse citationwizard api key daily snapshots
   up     20260316071735  Rename automation api key scope resource
   up     20260316071736  Rename ai api key scope resource
   up     20260316071737  Rename data explorer api key scope resource
   up     20260319000000  ********** NO FILE **********
   up     20260319000001  Create discourse citationwizard user lookup events
   up     20260319000002  Create discourse citationwizard citation wizard sessions
   up     20260319033623  ********** NO FILE **********
   up     20260319055039  ********** NO FILE **********

And discourse-citationwizard (that supports https://www.citationwizard.net/, a citation/reference tool for academics) made a migration the same day. I thought that migration looked suspect, but didn’t have an idea that there would be implications like this. . .

So that’s why plugins/discourse-ai/db/migrate/20260319000001_create_ai_agent_mcp_servers.rb can’t run.

And I had the bad luck that my migration ran first (it’s easier to change my code than yours). I’m trying now to see if I can rename my migrations in the migration table. . .

:facepalm:

We do have this instruction in AI-AGENTS.md:

But I guess it’s ignoring it :person_shrugging:

@sam did you use any specific skill/prompt to make these discourse-ai migrations? If we can try to use real timestamps rather than suspiciously-specific numbers ending in 0000, that would really help avoid collisions :thinking:

1 Like

And I ran this from in your repo to take advantage of your superior knowledge of the AI. And I’m now vindicated in knowing that a team of experts can’t do any better than I am!

So, yeah, Claude, WHY NOT USE GENERATE MIGRATION!?!?!?

I changed the migration version in the database like this:

UPDATE schema_migrations 
SET version   = '20260319001231' 
WHERE version = '20260319000001';

And renamed the migration in my plugin to match. That did the trick!

I’d blame myself for not pulling from discourse main as often as I should, but it was the same day, so even if I did it every day, it wouldn’t have helped. I guess I should pull from main and running migrations one more time before pushing, maybe. But I won’t let a migration like this happen again.

Thanks so much for your help. This was definitely a weird edge case that would never happen if we weren’t both using AI on the same day.

1 Like