Bug: IRB history not saved when using `debug` with `RUBY_DEBUG_IRB_CONSOLE=true`
Versions
- irb: 1.15.2
- debug: 1.11.0
- Ruby: 3.3.6
- OS: MacOS
Description
When running an IRB session launched from a script under debug with RUBY_DEBUG_IRB_CONSOLE=true, command history is not written to ~/.irb_history.
The same script, run without RUBY_DEBUG_IRB_CONSOLE=true, saves history as expected.
Reproduction
# script.rb
require "debug"
require "irb"
IRB.start
Run:
RUBY_DEBUG_IRB_CONSOLE=true bundle exec ruby script.rb
# type several IRB commands, then exit
Check ~/.irb_history — the commands you typed aren’t appended.
Control case (works):
bundle exec ruby script.rb
# type several IRB commands, then exit
Now ~/.irb_history contains the new commands.
Expected behavior
The interactive IRB session started by the script should append commands to ~/.irb_history even if RUBY_DEBUG_IRB_CONSOLE is set.
Analysis
When RUBY_DEBUG_IRB_CONSOLE=true is set, debug eagerly creates its own IRB console in the background.
That causes IRB’s “first session” detection (via MAIN_CONTEXT) to treat the user-visible session as nested rather than the initial one.
Because IRB only persists history from the first session, the foreground session never saves history.
The logic that gates history saving based on the main vs. nested session seems tied to this commit in Ruby’s repo:
- [ruby/ruby@ab0f90f1f5583a64a125701e3b08f6620f029eb6](https://github.com/ruby/ruby/commit/ab0f90f1f5583a64a125701e3b08f6620f029eb6)
Why I think this is a bug
From a user perspective, the interactive session the user is typing into should save history regardless of whether a background IRB console was created by a debugger.
Today, enabling RUBY_DEBUG_IRB_CONSOLE=true flips that behavior in a surprising and unintuitive way.
Workarounds
- Run without
RUBY_DEBUG_IRB_CONSOLE=true(history is saved). - Add to
~/.irbrc
if defined?(DEBUGGER__) && ENV["RUBY_DEBUG_IRB_CONSOLE"] == "true"
IRB.conf[:AT_EXIT] << proc {
if IRB.conf[:MAIN_CONTEXT]&.io.respond_to?(:save_history)
IRB.conf[:MAIN_CONTEXT].io.save_history
end
}
end
Context
Discovered while migrating from Pry/Byebug to IRB + debug.
@st0012 I noticed that you authored the commit introducing this behavior in the IRB integration.
Do you happen to know if this was intentional, or just an unintended side effect of the nested session handling?
It seems to cause IRB history not to persist when running under RUBY_DEBUG_IRB_CONSOLE=true, since the main context gets overridden by the debugger’s internal console. Curious to hear your thoughts on whether this should be adjusted.