irb icon indicating copy to clipboard operation
irb copied to clipboard

Bug: IRB history not saved when using `debug` with `RUBY_DEBUG_IRB_CONSOLE=true`

Open jvlara opened this issue 2 months ago • 1 comments

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:

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.

jvlara avatar Oct 17 '25 13:10 jvlara

@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.

jvlara avatar Oct 17 '25 14:10 jvlara