bundle exec rake db:migrate RAILS_ENV=production -> NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError)
Added by David Gessel 3 months ago
Environment¶
redmine51-5.1.3_2
FreeBSD 14.1-RELEASE-p3 GENERIC amd64
ruby-3.2.5,1
rubygem-rails61-6.1.7.8
mariadb105-server-10.5.16
Environment production
- bundle exec rake about RAILS_ENV=production
About your application's environment Rails version 6.1.7.8 Ruby version ruby 3.2.5 (2024-07-26 revision 31d0f1a2e7) [amd64-freebsd14] RubyGems version 3.5.18 Rack version 2.2.9 Middleware ActionDispatch::HostAuthorization, Rack::ContentLength, Rack::Sendfile, ActionDispatch::Static, ActionDispatch::Executor, ActiveSupport::Cache::Strategy::LocalCache::Middleware, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, RequestStore::Middleware, ActionDispatch::RemoteIp, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::ActionableExceptions, ActionDispatch::Callbacks, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ContentSecurityPolicy::Middleware, ActionDispatch::PermissionsPolicy::Middleware, Rack::Head, Rack::ConditionalGet, Rack::ETag, Rack::TempfileReaper Application root /usr/local/www/redmine Environment production
Errors¶
Attempting to upgrade to current, I get stopped by an error that I'm not finding much help from search for:
$ bundle exec rake db:migrate RAILS_ENV=production WARNING: Nokogiri was built against libxml version 2.11.8, but has dynamically loaded 2.11.9 rake aborted! NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) variables = @config.fetch(:variables, {}).stringify_keys ^^^^^^^^^^^^^^^ /usr/local/bin/bundle:25:in `load' /usr/local/bin/bundle:25:in `<main>' Tasks: TOP => db:migrate (See full trace by running task with --trace)
I can run with --trace if that's helpful.
Replies (8)
RE: bundle exec rake db:migrate RAILS_ENV=production -> NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) - Added by David Gessel 3 months ago
I forgot to mention, this is an update from redmine42-4.2.5 with a clean install, just moved database.yml, settings.yml, and /files to the new folder, no plugins migrated yet.
RE: bundle exec rake db:migrate RAILS_ENV=production -> NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) - Added by Holger Just 3 months ago
The code quoted in the error message is not part of Redmine 5.1.3. You can get more information by appending --trace
to your command. Depending on the source of your Redmine code, someone may have adapted it.
In any case, note that the config/settings.yml
file is specific to the respective Redmine version and you must not edit or replace it with an old version. See RedmineUpgrade for complete upgrade instructions.
RE: bundle exec rake db:migrate RAILS_ENV=production -> NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) - Added by David Gessel 3 months ago
Thanks for the help!
The source is https://www.freshports.org/www/redmine51/
Code for the FreeBSD port is https://github.com/freebsd/freebsd-ports/tree/main/www/redmine51
A few files are patched for FreeBSD.
To test in isolation, I did a completely new install, fresh database, no modifications to configuration.yml
and only the database.yml
settings to connect to the new database (noting that MariaDB throws an error with either the transaction_isolation
or the tx_isolation
variable set. The only modifications to the as-shipped /redmine
folder are the following database.yml
configurations:
# Default setup is given for MySQL 5.7.7 or later. # Examples for PostgreSQL, SQLite3 and SQL Server can be found at the end. # Line indentation must be 2 spaces (no tabs). production: adapter: mysql2 database: redmine5t host: 10.3.69.183 username: redmine5t password: "randompassword" # Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7 encoding: utf8mb4 variables: # Recommended `transaction_isolation` for MySQL to avoid concurrency issues is # `READ-COMMITTED`. # In case of MySQL lower than 8, the variable name is `tx_isolation`. # See https://www.redmine.org/projects/redmine/wiki/MySQL_configuration # should be updated to "transaction_isolation" after db update (then test) # transaction_isolation: "tx_isolation" development: adapter: mysql2 database: redmine_development host: localhost username: root password: "" # Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7 encoding: utf8mb4 variables: transaction_isolation: "READ-COMMITTED" # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: mysql2 database: redmine_test host: localhost username: root password: "" # Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7 encoding: utf8mb4 variables: transaction_isolation: "READ-COMMITTED"
Then the following command sequence yields:
$ whoami redmine $ bundle config set --local without 'development test' You are replacing the current local value of without, which is currently "development:test" $ bundle install Bundle complete! 30 Gemfile dependencies, 75 gems now installed. Gems in the groups 'development' and 'test' were not installed. Use `bundle info [gemname]` to see where a bundled gem is installed. $ RAILS_ENV=production bundle exec rake db:migrate --trace ** Invoke db:migrate (first_time) ** Invoke db:load_config (first_time) ** Invoke environment (first_time) ** Execute environment ** Execute db:load_config ** Execute db:migrate rake aborted! NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) variables = @config.fetch(:variables, {}).stringify_keys ^^^^^^^^^^^^^^^ /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:744:in `configure_connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/mysql2_adapter.rb:144:in `configure_connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/mysql2_adapter.rb:53:in `initialize' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/mysql2_adapter.rb:22:in `new' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/mysql2_adapter.rb:22:in `mysql2_connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:882:in `public_send' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:882:in `new_connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:926:in `checkout_new_connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:905:in `try_to_checkout_new_connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:866:in `acquire_connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:588:in `checkout' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:428:in `connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:1128:in `retrieve_connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_handling.rb:327:in `retrieve_connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_handling.rb:283:in `connection' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/tasks/database_tasks.rb:237:in `migrate' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/railties/databases.rake:92:in `block (3 levels) in <top (required)>' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/railties/databases.rake:90:in `each' /usr/local/lib/ruby/gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/railties/databases.rake:90:in `block (2 levels) in <top (required)>' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/task.rb:281:in `block in execute' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/task.rb:281:in `each' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/task.rb:281:in `execute' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/task.rb:219:in `block in invoke_with_call_chain' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/task.rb:199:in `synchronize' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/task.rb:199:in `invoke_with_call_chain' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/task.rb:188:in `invoke' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/application.rb:188:in `invoke_task' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/application.rb:138:in `block (2 levels) in top_level' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/application.rb:138:in `each' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/application.rb:138:in `block in top_level' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/application.rb:147:in `run_with_threads' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/application.rb:132:in `top_level' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/application.rb:83:in `block in run' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/application.rb:214:in `standard_exception_handling' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/lib/rake/application.rb:80:in `run' /usr/local/lib/ruby/gems/3.2/gems/rake-13.2.1/exe/rake:27:in `<top (required)>' /usr/local/bin/rake:25:in `load' /usr/local/bin/rake:25:in `<top (required)>' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/cli/exec.rb:58:in `load' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/cli/exec.rb:58:in `kernel_load' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/cli/exec.rb:23:in `run' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/cli.rb:455:in `exec' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/vendor/thor/lib/thor/command.rb:28:in `run' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/vendor/thor/lib/thor.rb:527:in `dispatch' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/cli.rb:35:in `dispatch' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/vendor/thor/lib/thor/base.rb:584:in `start' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/cli.rb:29:in `start' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/exe/bundle:28:in `block in <top (required)>' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors' /usr/local/lib/ruby/gems/3.2/gems/bundler-2.5.14/exe/bundle:20:in `<top (required)>' /usr/local/bin/bundle:25:in `load' /usr/local/bin/bundle:25:in `<main>' Tasks: TOP => db:migrate
RE: bundle exec rake db:migrate RAILS_ENV=production -> NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) - Added by David Gessel 3 months ago
Also, poking a bit more:
/usr/local/www/redmine # grep -r "stringify_keys" * app/models/query.rb: json[field] = options.stringify_keys app/models/project.rb: initialized = (attributes || {}).stringify_keys app/models/issue.rb: attrs.stringify_keys! lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb: v = v.stringify_keys lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb: values = values.stringify_keys lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb: attachments = attachments.stringify_keys lib/redmine/configuration.rb: settings.stringify_keys!
RE: bundle exec rake db:migrate RAILS_ENV=production -> NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) - Added by David Gessel 3 months ago
oops, here:
gems/3.2/gems/activerecord-4.2.11.3/lib/active_record/connection_adapters/abstract_mysql_adapter.rb: variables = @config.fetch(:variables, {}).stringify_keys
RE: bundle exec rake db:migrate RAILS_ENV=production -> NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) - Added by David Gessel 3 months ago
Cleaned up the gems files so the result is now:
# grep -r "variables, {}).stringify_keys" * gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/postgresql_adapter.rb: variables = @config.fetch(:variables, {}).stringify_keys gems/3.2/gems/activerecord-6.1.7.8/lib/active_record/connection_adapters/abstract_mysql_adapter.rb: variables = @config.fetch(:variables, {}).stringify_keys
Since mysql is configured it is almost certainly the second that is throwing the error.
RE: bundle exec rake db:migrate RAILS_ENV=production -> NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) - Added by Holger Just 3 months ago
Okay, the cause of the error is Rails which reads your config/database.yml
. In your file, you have defined an empty variables
section within your production environment, which is thus parsed as `nil`. To fix this, when not setting any variables, you should comment out (or remove) the variables
section entirely from your database.yml
, e.g.:
# Default setup is given for MySQL 5.7.7 or later.
# Examples for PostgreSQL, SQLite3 and SQL Server can be found at the end.
# Line indentation must be 2 spaces (no tabs).
production:
adapter: mysql2
database: redmine5t
host: 10.3.69.183
username: redmine5t
password: "randompassword"
# Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7
encoding: utf8mb4
# variables:
# # Recommended `transaction_isolation` for MySQL to avoid concurrency issues is
# # `READ-COMMITTED`.
# # In case of MySQL lower than 8, the variable name is `tx_isolation`.
# # See https://www.redmine.org/projects/redmine/wiki/MySQL_configuration
# # should be updated to "transaction_isolation" after db update (then test)
# transaction_isolation: "tx_isolation"
development:
adapter: mysql2
database: redmine_development
host: localhost
username: root
password: ""
# Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7
encoding: utf8mb4
variables:
transaction_isolation: "READ-COMMITTED"
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: mysql2
database: redmine_test
host: localhost
username: root
password: ""
# Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7
encoding: utf8mb4
variables:
transaction_isolation: "READ-COMMITTED"
RE: bundle exec rake db:migrate RAILS_ENV=production -> NoMethodError: undefined method `stringify_keys' for nil:NilClass (NoMethodError) - Added by David Gessel 3 months ago
Figured it out - The problem is I commented out the recommended required value for transaction_isolation
and you'll note my confused insertion of the key tx_isolation
for the value in the pair.
Commenting out the key causes a null value to be passed to /abstract_mysql_adapter.rb:744
which doesn't have any input sanitizing. The undefined method
error message is terribly misleading as the actual problem is a null value. My clue was this fine post: NoMethodError: undefined method for nil:NilClass... Explained
Armed with that data, I needed to decode why any of the possible values for transaction_isolation
created a different error:
$ bundle config set --local without 'development test' You are replacing the current local value of without, which is currently "development:test" $ RAILS_ENV=production bundle exec rake db:migrate --trace (in /usr/local/www/redmine) ** Invoke db:migrate (first_time) ** Invoke db:load_config (first_time) ** Invoke environment (first_time) ** Execute environment ** Execute db:load_config ** Execute db:migrate rake aborted! ActiveRecord::StatementInvalid: Mysql2::Error: Unknown system variable 'transaction_isolation' (ActiveRecord::StatementInvalid)
This seemed easy to avoid by simply commenting out the
transaction_isolation
declaration to get started.
It was not. Because above.
And it turns out that for MariaDB, at least MariaDB 10.5.16, the correct recommended required key value pair is:
tx_isolation: "READ-COMMITTED"
And after that, it's just the usual quirks of Ruby. Now to flush and restart with the historical data.