Issue #22421 has been updated by znz (Kazuhiro NISHIYAMA). I checked the released branches. `RubyVM::YJIT.max_compile_time_ns=` (and `max_compile_time_ns` / `total_compile_time_ns`) was added to master by c29739cb3 (2026-09-24, [Feature #22236]) and does not exist in `ruby_3_3`, `ruby_3_4` or `ruby_4_0` (`yjit.rb` on those branches has no `max_compile_time_ns`): ``` $ ruby -v ruby 3.3.11 (2026-03-26 revision 1f2d15125a) [x86_64-linux] $ ruby -e 'RubyVM::YJIT.max_compile_time_ns = 10' -e:1:in `<main>': undefined method `max_compile_time_ns=' for module RubyVM::YJIT (NoMethodError) ``` The same `NoMethodError` is raised on 3.4.11 and 4.0.7 (`ghcr.io/ruby/ruby:3.4` / `:4.0`). I also called every other `RubyVM::YJIT` singleton method with YJIT not enabled on 3.3.11, 3.4.11, 4.0.7 and master (`code_gc`, `enable`, `enabled?`, `exit_locations`, `log`, `log_enabled?`, `reset_stats!`, `runtime_stats`, `simulate_oom!`, `stats_enabled?`, `stats_string`, `trace_exit_locations_enabled?` without arguments; `disasm` and `insns_compiled` with an ISeq; `dump_exit_locations` with a file name). None of them aborts (they return `nil`/`false` or raise an `ArgumentError`), so the crash is limited to the new setter on master. The backport field can be set to DONTNEED for 3.3, 3.4 and 4.0. 🤖 Generated with [Claude Code](https://claude.com/claude-code) ---------------------------------------- Bug #22421: `RubyVM::YJIT.max_compile_time_ns=` aborts the process when YJIT is not enabled https://bugs.ruby-lang.org/issues/22421#change-119456 * Author: znz (Kazuhiro NISHIYAMA) * Status: Open * Assignee: jit * ruby -v: ruby 4.1.0dev (2026-10-09T00:54:42Z master 21f68cfec7) +PRISM [x86_64-linux] * Backport: 3.3: DONTNEED, 3.4: DONTNEED, 4.0: DONTNEED ---------------------------------------- Calling `RubyVM::YJIT.max_compile_time_ns=` (added by [Feature #22236]) before YJIT is enabled aborts the process with a Rust panic. ``` $ ruby -v ruby 4.1.0dev (2026-10-09T00:54:42Z master 21f68cfec7) +PRISM [x86_64-linux] $ ruby -e 'RubyVM::YJIT.max_compile_time_ns = 10' thread '<unnamed>' (10) panicked at /usr/src/ruby/yjit/src/codegen.rs:11313:43: called `Option::unwrap()` on a `None` value note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace thread '<unnamed>' (10) panicked at .../library/core/src/panicking.rs:225:5: panic in a function that cannot unwind Aborted (core dumped) ``` The same happens with `ruby --yjit-disable -e 'RubyVM::YJIT.max_compile_time_ns = 10'`. It works as expected once YJIT is enabled, either with `--yjit` or after `RubyVM::YJIT.enable`: ``` $ ruby --yjit -e 'RubyVM::YJIT.max_compile_time_ns = 10; p RubyVM::YJIT.max_compile_time_ns' 10 $ ruby -e 'RubyVM::YJIT.enable; RubyVM::YJIT.max_compile_time_ns = 10; p RubyVM::YJIT.max_compile_time_ns' 10 ``` The reader side does not crash (`RubyVM::YJIT.max_compile_time_ns` and `RubyVM::YJIT.total_compile_time_ns` return 0 when YJIT is not enabled). The panic is the `unwrap()` in `CodegenGlobals::get_instance()` (yjit/src/codegen.rs), which is `None` until YJIT is initialized. Other YJIT methods that touch the globals (for example `reset_stats!` or `enable`) check `CodegenGlobals::has_instance()` or the enabled state first. Expected behavior: either store the value so that it takes effect when YJIT is enabled later (useful for the warmup-budget use case in [Feature #22236], where the budget may be set early in a boot script), or raise a Ruby exception, but not abort the process. Reproduced in the `ghcr.io/ruby/ruby:master` Docker image (x86_64-linux). -- https://bugs.ruby-lang.org/