dry-rb / dry-rails

The official dry-rb railtie

Home Page:https://dry-rb.org/gems/dry-rails

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Got FrozenError after dry-core upgrade to 0.9.1

elct9620 opened this issue · comments

Describe the bug

The ActiveSupport::Dependencies.autoload_paths is frozen but still some autoload paths is attached.

debug gem trace

DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:73 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:61 [] receives #<< (Array#<<) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/actionmailer-7.0.4/lib/action_mailer/railtie.rb:72
DEBUGGER (trace/object) #th:1 #depth:61 [] receives #freeze (Kernel#freeze) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/application/finisher.rb:20
DEBUGGER (trace/object) #th:1 #depth:61 [] receives #uniq (Array#uniq) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/application/finisher.rb:21
Tapioca attempted to load the Rails application after encountering a `config/application.rb` file, but it failed. If your application uses Rails please ensure it can be loaded correctly before generating RBIs.
uninitialized constant Dry::Validation::Contract::ClassInterface

      extend ClassInterface
             ^^^^^^^^^^^^^^
Continuing RBI generation without loading the Rails application.
Done
DEBUGGER (trace/object) #th:1 #depth:94 [] receives #unshift (Array#unshift) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574
DEBUGGER (trace/object) #th:1 #depth:95 [] receives #inspect (Array#inspect) at ~/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/railties-7.0.4/lib/rails/engine.rb:574

To Reproduce

Reference this file to remove dry-core version pin and update it to reproduce
https://github.com/BasalticStudio/new-era/blob/e52e10fae29dda85d0c635a4da6421ba176c78cd/Gemfile

Unable to reproduce in other projects that have the same version (without dry-rails) and I am tracing it.

Updated - 1

ruby debug gem with:

b ActiveSupport::Dependencies.autoload_paths do: info

When #freeze is called, the Rails seems to continue running the initializer again.

Updated - 2

It is caused by dry-validation ~> 1.9.0 cannot correct load the module

/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/dry-validation-1.9.0/lib/dry/validation/contract.rb:47:in `<class:Contract>': uninitialized constant Dry::Validation::Contract::ClassInterface (NameError)

      extend ClassInterface
             ^^^^^^^^^^^^^^

If downgraded to 1.8.1 other dry gem have same issue.

Expected behavior

The initializer should not be called after the freeze.

My environment

  • Affects my production application: YES
  • Ruby version: 3.0.4 or 3.1.2 are breaks
  • OS: macOS/Linux

I'm seeing the same issue, as well. Using dry-rails at 0.5.0 (among others detailed below), there is a NameError exception thrown during the Rails initialization process. Prior to the dry-validation 0.9.0 upgrade, the app boots are runs without issue.

dry-validation initialization error:

Failure/Error: require File.expand_path('../../config/environment', __FILE__)

NameError:
  uninitialized constant Dry::Validation::Contract::ClassInterface
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-validation-1.9.0/lib/dry/validation/contract.rb:47:in `<class:Contract>'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-validation-1.9.0/lib/dry/validation/contract.rb:43:in `<module:Validation>'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-validation-1.9.0/lib/dry/validation/contract.rb:10:in `<module:Dry>'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-validation-1.9.0/lib/dry/validation/contract.rb:9:in `<top (required)>'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/zeitwerk-2.6.1/lib/zeitwerk/kernel.rb:35:in `require'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/zeitwerk-2.6.1/lib/zeitwerk/kernel.rb:35:in `require'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-rails-0.5.0/lib/dry/rails/features/application_contract.rb:3:in `<top (required)>'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/zeitwerk-2.6.1/lib/zeitwerk/kernel.rb:35:in `require'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/zeitwerk-2.6.1/lib/zeitwerk/kernel.rb:35:in `require'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-rails-0.5.0/lib/dry/rails/boot/application_contract.rb:5:in `block (2 levels) in <top (required)>'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider.rb:231:in `public_send'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider.rb:231:in `run_step'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider.rb:167:in `start'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider_registrar.rb:149:in `each_value'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider_registrar.rb:149:in `finalize!'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/container.rb:360:in `finalize!'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-rails-0.5.0/lib/dry/rails/railtie.rb:64:in `finalize!'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/railties-7.0.4/lib/rails/railtie.rb:226:in `public_send'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/railties-7.0.4/lib/rails/railtie.rb:226:in `method_missing'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-rails-0.5.0/lib/dry/rails/railtie.rb:16:in `block in <class:Railtie>'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:445:in `instance_exec'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:445:in `block in make_lambda'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:199:in `block (2 levels) in halting'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:687:in `block (2 levels) in default_terminator'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:686:in `catch'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:686:in `block in default_terminator'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:200:in `block in halting'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:595:in `block in invoke_before'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:595:in `each'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:595:in `invoke_before'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:106:in `run_callbacks'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/activesupport-7.0.4/lib/active_support/reloader.rb:88:in `prepare!'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/railties-7.0.4/lib/rails/application/finisher.rb:68:in `block in <module:Finisher>'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/railties-7.0.4/lib/rails/initializable.rb:32:in `instance_exec'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/railties-7.0.4/lib/rails/initializable.rb:32:in `run'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/railties-7.0.4/lib/rails/initializable.rb:61:in `block in run_initializers'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/tsort.rb:228:in `block in tsort_each'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/tsort.rb:431:in `each_strongly_connected_component_from'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/tsort.rb:349:in `block in each_strongly_connected_component'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/tsort.rb:347:in `each'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/tsort.rb:347:in `call'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/tsort.rb:347:in `each_strongly_connected_component'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/tsort.rb:226:in `tsort_each'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/tsort.rb:205:in `tsort_each'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/railties-7.0.4/lib/rails/initializable.rb:60:in `run_initializers'
# /home/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/railties-7.0.4/lib/rails/application.rb:372:in `initialize!'
# ./config/environment.rb:7:in `<top (required)>'
# ./spec/rails_helper.rb:5:in `require'
# ./spec/rails_helper.rb:5:in `<top (required)>'

dry-* dependency differences between working and not working application upgrade is:

  * dry-auto_inject (0.9.0)                                       * dry-auto_inject (0.9.0)
  * dry-configurable (0.16.1)                                     * dry-configurable (0.16.1)
  * dry-container (0.11.0)                                        * dry-container (0.11.0)
  * dry-core (0.9.1)                                              * dry-core (0.9.1)
  * dry-equalizer (0.3.0)                                         * dry-equalizer (0.3.0)
  * dry-events (0.4.0)                                            * dry-events (0.4.0)
  * dry-inflector (0.3.0)                                         * dry-inflector (0.3.0)
  * dry-initializer (3.1.1)                                       * dry-initializer (3.1.1)
  * dry-logic (1.3.0)                                             * dry-logic (1.3.0)
  * dry-matcher (0.9.0)                                           * dry-matcher (0.9.0)
  * dry-monads (1.5.0)                                            * dry-monads (1.5.0)
  * dry-rails (0.5.0)                                             * dry-rails (0.5.0)
  * dry-schema (1.10.6)                                       |   * dry-schema (1.11.2)
  * dry-struct (1.5.2)                                            * dry-struct (1.5.2)
  * dry-system (0.27.2)                                           * dry-system (0.27.2)
  * dry-transaction (0.13.3)                                      * dry-transaction (0.13.3)
  * dry-transformer (0.1.1)                                       * dry-transformer (0.1.1)
  * dry-types (1.6.1)                                             * dry-types (1.6.1)
  * dry-validation (1.8.1)                                    |   * dry-validation (1.9.0)

I'm guessing that there's some load order or requirement weirdness with the recent zeitwerk changes across the libraries which introduced this issue to dry-rails.

Please upgrade to dry-rails 0.6.0 where it should work

@solnic Thank you! 👏. Attempting an upgrade now and I'll post back, shortly.

@solnic thanks 👏 My project is working correctly again.

Well, I got a different error now. 😀 I'll look into that and see if it's on my side or in the upgrade/dependency chain... either way, this NameError issue certainly seems to be corrected. Thank you again!

Failure/Error: require File.expand_path('../../config/environment', __FILE__)

Dry::System::ProviderSourceNotFoundError:
  Provider source not found: :settings, group: :dry_systemAvailable provider sources:

  ["- :application_contract, group: :rails", "- :controller_helpers, group: :rails", "- :safe_params, group: :rails"]
# /Users/nate/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider_source_registry.rb:52:in `block in resolve'
# /Users/nate/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider_source_registry.rb:50:in `tap'
# /Users/nate/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider_source_registry.rb:50:in `resolve'
# /Users/nate/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider_registrar.rb:234:in `build_provider_from_source'
# /Users/nate/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/provider_registrar.rb:57:in `register_provider'
# /Users/nate/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/dry-system-0.27.2/lib/dry/system/container.rb:289:in `register_provider'
# ./config/system/boot/settings.rb:3:in `<top (required)>'

@nbibler oh :/ which version of dry-system did you have before? We've been making some Hanami-related tweaks in dry-system lately as a preparation for dry-system 1.0.0 and you're probably affected. I should be able to help resolve this though.

@solnic : I think the only changes were dry-validation (1.8.1 -> 1.9.0), dry-schema (1.10.6 -> 1.11.2), and the dry-rails bump (0.5.0 -> 0.6.0):

diff --git a/Gemfile b/Gemfile
index 92e718ad9..ef7bc316b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -27,7 +27,7 @@ gem 'doorkeeper-jwt', '~> 0.4.0'
 gem 'dotenv-rails', '~> 2.0'
 gem 'dry-matcher', '~> 0.9.0'
 gem 'dry-monads', '~> 1.0'
-gem 'dry-rails', '~> 0.5.0'
+gem 'dry-rails', '~> 0.6.0'
 gem 'dry-struct', '~> 1.2'
 gem 'dry-transaction', '~> 0.13.0'
 gem 'dry-transformer', '~> 0.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 6a3207aa5..c5f0fb21a 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -223,17 +223,18 @@ GEM
       concurrent-ruby (~> 1.0)
       dry-core (~> 0.9, >= 0.9)
       zeitwerk (~> 2.6)
-    dry-rails (0.5.0)
-      dry-schema (~> 1.7)
-      dry-system (~> 0.23, >= 0.23)
-      dry-validation (~> 1.5)
-    dry-schema (1.10.6)
+    dry-rails (0.6.0)
+      dry-schema (~> 1.11, >= 1.11.2)
+      dry-system (~> 0.27, >= 0.27.2)
+      dry-validation (~> 1.9, >= 1.9.0)
+    dry-schema (1.11.2)
       concurrent-ruby (~> 1.0)
-      dry-configurable (~> 0.13, >= 0.13.0)
-      dry-core (~> 0.5, >= 0.5)
+      dry-configurable (~> 0.16, >= 0.16)
+      dry-core (~> 0.9, >= 0.9)
       dry-initializer (~> 3.0)
-      dry-logic (~> 1.2)
-      dry-types (~> 1.5)
+      dry-logic (~> 1.3)
+      dry-types (~> 1.6)
+      zeitwerk (~> 2.6)
     dry-struct (1.5.2)
       dry-core (~> 0.9, >= 0.9)
       dry-types (~> 1.6)
@@ -259,12 +260,13 @@ GEM
       dry-inflector (~> 0.1, >= 0.1.2)
       dry-logic (~> 1.3, >= 1.3)
       zeitwerk (~> 2.6)
-    dry-validation (1.8.1)
+    dry-validation (1.9.0)
       concurrent-ruby (~> 1.0)
       dry-container (~> 0.7, >= 0.7.1)
-      dry-core (~> 0.5, >= 0.5)
+      dry-core (~> 0.9, >= 0.9)
       dry-initializer (~> 3.0)
-      dry-schema (~> 1.8, >= 1.8.0)
+      dry-schema (~> 1.11, >= 1.11.0)
+      zeitwerk (~> 2.6)
     equivalent-xml (0.6.0)
       nokogiri (>= 1.4.3)
     erubi (1.11.0)
@@ -727,7 +729,7 @@ DEPENDENCIES
   dotenv-rails (~> 2.0)
   dry-matcher (~> 0.9.0)
   dry-monads (~> 1.0)
-  dry-rails (~> 0.5.0)
+  dry-rails (~> 0.6.0)
   dry-struct (~> 1.2)
   dry-transaction (~> 0.13.0)
   dry-transformer (~> 0.1)

@nbibler hmmm does it work when you add require "dry/system/provider_sources" to config/initializers/system.rb?

@solnic: Yep! That seems to fix it. 😄 Thanks again! 👏

@nbibler 😅 good, sorry for the trouble. I think we should make it lazy-loadable in dry-system. I reported an issue about it: dry-rb/dry-system#252

No problem at all! Thanks for the rapid responses and help!