Keep completion alive when RDoc document retrieval fails#1229
Merged
Conversation
## Summary The autocompletion documentation dialog could crash the whole IRB session when loading RDoc documentation failed. This makes RDoc document retrieval failable: the error is shown in the dialog and completion (and the session) keeps working. ## Steps to reproduce With `Ruby::Box` enabled, IRB crashes during completion (see the details below). The steps below reproduce it that way, but the crash can happen in any case where loading RDoc documentation fails, not only under `Ruby::Box`. 1. Use a Ruby build that provides `Ruby::Box` (e.g. a ruby-dev build) and start IRB with the box enabled: ``` RUBY_BOX=1 irb ``` 2. Type `1.` and press <Tab> to trigger method-name completion. Any receiver reproduces it; the trigger is rendering the documentation dialog for a completion candidate, which loads RDoc data from disk. ## Expected behavior The completion candidates and their documentation dialog are shown, and IRB keeps running even when the documentation cannot be loaded. ## Actual behavior IRB terminates with an uncaught exception: ``` .../rdoc/store.rb:1190:in 'Marshal.load': undefined class/module RDoc:: (ArgumentError) from .../rdoc/store.rb:1190:in 'block in RDoc::Store#marshal_load' from .../rdoc/store.rb:835:in 'RDoc::Store#load_method' ... from .../irb/input-method.rb:in 'IRB::RelineInputMethod#rdoc_dialog_contents' from .../reline/line_editor.rb:in 'Reline::LineEditor::Dialog#call' ... ``` ## Environment ``` irb(main):001> irb_info Ruby version: 4.0.6 IRB version: irb 1.18.0 (2026-04-21) InputMethod: RelineInputMethod with Reline 0.6.3 Completion: Autocomplete, ReplTypeCompletor: 0.1.12, Prism: 1.8.1, RBS: 3.10.0 .irbrc paths: /home/pocke/.irbrc RUBY_PLATFORM: x86_64-linux LANG env: C.UTF-8 East Asian Ambiguous Width: 1 ``` ## Root cause The dialog loads RDoc `.ri` data via `Marshal.load`, and `rdoc_dialog_contents` only rescued `RDoc::RI::Driver::NotFoundError`. Any other error raised during retrieval propagated through Reline's dialog proc and terminated the REPL. Here it is triggered by a Ruby core bug: under `Ruby::Box` (`RUBY_BOX=1`), `Marshal.load` fails to resolve class references and raises `ArgumentError: undefined class/module ...` (https://bugs.ruby-lang.org/issues/22090). That bug lives in Ruby itself and cannot be fixed here, but RDoc document retrieval is a fragile external dependency that IRB should treat as failable regardless of the specific cause. ## Fix Treat only the fragile part -- fetching the document from the RDoc driver -- as failable, and leave rendering untouched. - Extract the RDoc driver calls into `retrieve_rdoc_document`, and rescue around that call alone in `rdoc_dialog_contents`. `NotFoundError` still means "no document" and stays silent; any other `StandardError` is turned into an error document by `rdoc_error_document`. - `RDoc::Markup::ToAnsi` rendering and the dialog layout stay outside the rescue on purpose: a failure there is IRB/Reline's own bug and should surface rather than be swallowed. - The error document shows the exception class and message where the document would appear, so the user learns why documentation is unavailable while completion keeps working. The "Press Alt+d to read the full document" hint is omitted on error, since there is no full document to open. - The narrow dialog does not show the backtrace. To investigate such a failure, run IRB with `-d` (which sets `$DEBUG`): the error is then re-raised with its full backtrace instead of being swallowed. The dialog points to this with a "Restart IRB with -d to see the backtrace." hint. ## Out of scope The Alt+D full-document path (`display_document`) is left unchanged. In the error state there is no document to open, so pressing Alt+D behaves as before.
pocke
force-pushed
the
keep-completion-alive-on-rdoc-error
branch
from
July 15, 2026 13:22
28c6734 to
d900ff8
Compare
pocke
marked this pull request as ready for review
July 15, 2026 13:46
tompng
approved these changes
Jul 16, 2026
tompng
left a comment
Member
There was a problem hiding this comment.
Looks good.
This will also fixes RDoc's Marshal load related problem such as http://github.com/ruby/rdoc/pull/1549
Thank you 👍
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The autocompletion documentation dialog could crash the whole IRB session when loading RDoc documentation failed. This makes RDoc document retrieval failable: the error is shown in the dialog and completion (and the session) keeps working.
Steps to reproduce
With
Ruby::Boxenabled, IRB crashes during completion (see the details below). The steps below reproduce it that way, but the crash can happen in any case where loading RDoc documentation fails, not only underRuby::Box.Use a Ruby build that provides
Ruby::Box(e.g. a ruby-dev build) and start IRB with the box enabled:Type
1.and press to trigger method-name completion.Any receiver reproduces it; the trigger is rendering the documentation dialog for a completion candidate, which loads RDoc data from disk.
Expected behavior
The completion candidates and their documentation dialog are shown, and IRB keeps running even when the documentation cannot be loaded.
Actual behavior
IRB terminates with an uncaught exception:
Screen records
before:
2026-07-15.224319.mp4
after:
2026-07-15.224351.mp4
Environment
Root cause
The dialog loads RDoc
.ridata viaMarshal.load, andrdoc_dialog_contentsonly rescuedRDoc::RI::Driver::NotFoundError. Any other error raised during retrieval propagated through Reline's dialog proc and terminated the REPL.Here it is triggered by a Ruby core bug: under
Ruby::Box(RUBY_BOX=1),Marshal.loadfails to resolve class references and raisesArgumentError: undefined class/module ...(https://bugs.ruby-lang.org/issues/22090). That bug lives in Ruby itself and cannot be fixed here, but RDoc document retrieval is a fragile external dependency that IRB should treat as failable regardless of the specific cause.Fix
Treat only the fragile part -- fetching the document from the RDoc driver -- as failable, and leave rendering untouched.
retrieve_rdoc_document, and rescue around that call alone inrdoc_dialog_contents.NotFoundErrorstill means "no document" and stays silent; any otherStandardErroris turned into an error document byrdoc_error_document.RDoc::Markup::ToAnsirendering and the dialog layout stay outside the rescue on purpose: a failure there is IRB/Reline's own bug and should surface rather than be swallowed.-d(which sets$DEBUG): the error is then re-raised with its full backtrace instead of being swallowed. The dialog points to this with a "Restart IRB with -d to see the backtrace." hint.Out of scope
The Alt+D full-document path (
display_document) is left unchanged. In the error state there is no document to open, so pressing Alt+D behaves as before.