Summary
ruby-head + ZJIT crashes booting a Rails app during eager-load:
undefined method 'to_sym' for an instance of Integer (NoMethodError)
activerecord-8.1.3/.../builder/collection_association.rb:33
callback_values = Array(options[callback_name.to_sym])
callback_name iterates [:before_add, :after_add, :before_remove, :after_remove], so it is always a Symbol. RUBY_ZJIT_ENABLE=0 boots fine; YJIT is off.
Bisected
First bad commit: 6803354732 "ZJIT: Move objtostring specialization to HIR build" (ruby#17499). Its parent 0a40bb7d0f boots fine. Bisected across the 06-22..06-29 nightlies, confirmed with from-source builds either side of ruby#17499.
Mechanism
The method interpolates callback_name, then calls to_sym on it:
full = "#{callback_name}_for_#{name}" # objtostring on callback_name
Array(options[callback_name.to_sym]) # callback_name now read as Integer
Repro
https://github.com/sampokuokkanen/zjit-rails-eager-load-repro
Could not get it to reproduce on a clean app with only a few models, so I had to distill the production app to the repro app.
Environment
ruby 4.1.0dev (2026-06-29 master 7402021a4a) +ZJIT +PRISM [aarch64-linux]; ZJIT on, YJIT off, RUBYOPT=--enable-frozen-string-literal (not required to trigger); activerecord 8.1.3.
Summary
ruby-head + ZJIT crashes booting a Rails app during eager-load:
callback_nameiterates[:before_add, :after_add, :before_remove, :after_remove], so it is always a Symbol.RUBY_ZJIT_ENABLE=0boots fine; YJIT is off.Bisected
First bad commit:
6803354732"ZJIT: Move objtostring specialization to HIR build" (ruby#17499). Its parent0a40bb7d0fboots fine. Bisected across the 06-22..06-29 nightlies, confirmed with from-source builds either side of ruby#17499.Mechanism
The method interpolates
callback_name, then callsto_symon it:Repro
https://github.com/sampokuokkanen/zjit-rails-eager-load-repro
Could not get it to reproduce on a clean app with only a few models, so I had to distill the production app to the repro app.
Environment
ruby 4.1.0dev (2026-06-29 master 7402021a4a) +ZJIT +PRISM [aarch64-linux]; ZJIT on, YJIT off,RUBYOPT=--enable-frozen-string-literal(not required to trigger); activerecord 8.1.3.