Skip to content

fix(ruby): don't fail gem installs when mise is not on PATH - #14850

Merged
jdx merged 3 commits into
mainfrom
claude/github-issue-14846-d1609f
Oct 23, 2026
Merged

jdx merged 3 commits into
mainfrom
claude/github-issue-14846-d1609f

Conversation

@jdx

@jdx jdx commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

https://entire.com/gh/jdx/mise/trails/972

Fixes #14846

gem: tools (and later bundle install) failed with Errno::ENOENT: No such file or directory - mise when mise wasn't on PATH, e.g. with the --localize install-script wrapper in CI. The rubygems plugin mise writes into each ruby shells out to mise reshim after every install, and that backtick call raised.

Now the plugin rescues the error and logs it under MISE_DEBUG, so the gem install succeeds. Reshimming is only a convenience for shim users. Rubies installed before this change pick it up on reinstall, since the plugin is written at ruby install time.

env -i PATH=<ruby>/bin ruby -e 'load "rubygems_plugin.rb"; ReshimInstaller.reshim'  # no longer raises

AI-assisted — Tool: Claude Code; model: anthropic/claude-sonnet-5-5; version: unavailable.

🤖 Generated with Claude Code


Note

Low Risk
Narrows failure to a debug log when optional post-install reshimming cannot run; no change to gem install or auth/data paths.

Overview
Fixes gem/bundle installs failing when mise is not on PATH (e.g. localized CI wrappers): the Rubygems plugin’s post-install mise reshim shell-out no longer raises SystemCallError / Errno::ENOENT.

ReshimInstaller.reshim now wraps the backtick call in begin/rescue, logs a skip under MISE_DEBUG, and lets the install finish—reshimming stays optional for shim users only.

Reviewed by Cursor Bugbot for commit 339337c. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Bug Fixes
    • Gem installations can now continue when refreshing tool shims encounters a system-level error. The skipped refresh is logged, while other types of errors continue to follow the existing behavior. This helps prevent a shim refresh issue from interrupting an otherwise successful gem installation.

Co-Authored-By: fxsalazar <fxsalazar@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M5HZYC0AJNND1521ME6396N0
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 48e837e and bbce9db.

📒 Files selected for processing: 1
  • src/plugins/core/assets/rubygems_plugin.rb

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

The RubyGems plugin now rescues SystemCallError raised by mise reshim and logs that reshimming was skipped. The gem-install flow can continue after this error.

Changes: RubyGems reshimming

Layer / File(s) Summary
Reshim error handling
src/plugins/core/assets/rubygems_plugin.rb
reshim rescues SystemCallError and logs that reshimming was skipped.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~5 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

Merge Risk: ⚪ Minimal · up to bbce9

The intended gem-install failure is addressed, with no actionable merge-blocking risk identified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: gem installs no longer fail when mise is not on PATH.
Linked Issues check Passed Issue #14846 requires gem: and bundle install flows to succeed when mise is not on PATH. The change in src/plugins/core/assets/rubygems_plugin.rb rescues SystemCallError, including `Errno:…
Out of Scope Changes check Passed The change is limited to error handling for the optional post-install mise reshim call in src/plugins/core/assets/rubygems_plugin.rb. This directly supports issue #14846. No unrelated install, aut…
Full details: Linked Issues check

Explanation

Issue #14846 requires gem: and bundle install flows to succeed when mise is not on PATH. The change in src/plugins/core/assets/rubygems_plugin.rb rescues SystemCallError, including Errno::ENOENT, from mise reshim. It logs the skipped reshim under debug logging and allows the install hook to continue. The issue states that non-fatal reshim handling is an acceptable fix. No additional coding requirement is specified.

Full details: Out of Scope Changes check

Explanation

The change is limited to error handling for the optional post-install mise reshim call in src/plugins/core/assets/rubygems_plugin.rb. This directly supports issue #14846. No unrelated install, authentication, or data-path changes are shown.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 RuboCop (1.91.0)
src/plugins/core/assets/rubygems_plugin.rb

invalid byte sequence in US-ASCII
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/target_ruby.rb:181:in 'Regexp#match'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/target_ruby.rb:181:in 'String#match'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/target_ruby.rb:181:in 'RuboCop::TargetRuby::RubyVersionFile#find_version'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/target_ruby.rb:31:in 'RuboCop::TargetRuby::Source#initialize'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/target_ruby.rb:295:in 'Class#new'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/target_ruby.rb:295:in 'block in RuboCop::TargetRuby#source'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/target_ruby.rb:295:in 'Array#each'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/target_ruby.rb:295:in 'Enumerator#each'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/target_ruby.rb:295:i

... [truncated 2433 characters] ...

ems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/config_store.rb:29:in 'RuboCop::ConfigStore#apply_options!'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/cli.rb:167:in 'RuboCop::CLI#act_on_options'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/cli.rb:49:in 'block in RuboCop::CLI#run'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/cli.rb:88:in 'RuboCop::CLI#profile_if_needed'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/lib/rubocop/cli.rb:45:in 'RuboCop::CLI#run'
/usr/local/lib/ruby/gems/3.4.0/gems/rubocop-1.91.0/exe/rubocop:15:in '<top (required)>'
/usr/local/lib/ruby/site_ruby/3.4.0/rubygems.rb:305:in 'Kernel#load'
/usr/local/lib/ruby/site_ruby/3.4.0/rubygems.rb:305:in 'Gem.activate_and_load_bin_path'
/usr/local/bin/rubocop:25:in '

'

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Low impact] The PR appears safe to merge.

Summary

Makes gem installs continue when mise reshim cannot start.

  • Ruby gem and Bundler installs continue when mise reshim cannot start.

Reviews (3) · Last reviewed commit: "Merge branch 'main' into claude/github-i..." · Reviewed by Greptile

@github-actions

Copy link
Copy Markdown
Contributor

Instruction counts

benchmark trend instructions Δ wall (min) Δ
env ▃▅▂▃▃█▇▅▁ 30,969,539 → 30,909,994 -0.19% 20.83 → 20.57ms -1.24%
hook-env ▃▄▃▃▄█▆▆▁ 33,257,244 → 33,195,009 -0.19% 21.81 → 21.83ms +0.05%
ls ▄▅▄▅▄▅█▃▁ 35,328,433 → 35,316,190 -0.03% 22.62 → 23.15ms +2.31%
registry ▁▁▁▁▄▃▆█▃ 43,883,201 → 43,798,505 -0.19% 18.52 → 19.07ms +2.95%
startup ▃▃▂▅▂▆█▄▁ 12,072,712 → 12,038,668 -0.28% 12.72 → 12.68ms -0.35%

No instruction-count regression above 1%.

Only instruction counts gate. Wall clock is shown for context — on identical hardware it moves 4-20% run to run.

Measured by tak — instruction-counted CLI benchmarks, stored in this repository's git notes.

339337c6d0ff vs 4e92675bf9fb · measured on the runner, not pushed to the history.

@jdx
jdx enabled auto-merge (squash) October 23, 2026 00:48
@jdx
jdx merged commit 10b0fa3 into main Oct 23, 2026
74 of 77 checks passed
@jdx
jdx deleted the claude/github-issue-14846-d1609f branch October 23, 2026 00:55
mise-en-dev added a commit that referenced this pull request Oct 23, 2026
<!-- entire-trail-link-start -->
https://entire.com/gh/jdx/mise/trails/949
<!-- entire-trail-link-end -->

### 🚀 Features

- **(bootstrap)** add run_windows to bootstrap hook tables by @jdx in
[#14851](#14851)
- **(doctor)** let a project check depend on another check by @jdx in
[#14773](#14773)
- **(dotfiles)** erase a tracked path from history with `mise dot
history purge` by @jdx in
[#14831](#14831)
- **(dotfiles)** render templates in a variant's target by @jdx in
[#14856](#14856)
- **(lsp)** add mise lsp, a language server for mise.toml by @jdx in
[#14744](#14744)
- **(lsp)** complete, define, and rename tasks by @jdx in
[#14808](#14808)
- **(lsp)** flag unknown task references and rewrite deprecated keys by
@jdx in [#14811](#14811)
- **(lsp)** complete and describe tools by @jdx in
[#14812](#14812)
- **(upgrade)** write resolved versions on bare --bump when pin is set
by @jdx in [#14791](#14791)

### 🐛 Bug Fixes

- **(aqua)** make the baked registry encoding deterministic by @jdx in
[#14809](#14809)
- **(backend)** reuse cached conda downloads in locked installs by
@zeitlinger in [#14866](#14866)
- **(bootstrap)** match only an exact bootstrap task by @jdx in
[#14858](#14858)
- **(brew)** tolerate custom Requirement classes in tap formulae by @jdx
in [#14807](#14807)
- **(config)** keep tracked .tool-versions recognized under a filename
override by @jdx in [#14779](#14779)
- **(dotfiles)** keep entries declared in an unselected env config
tracked by @jdx in [#14815](#14815)
- **(dotfiles)** report a saved enrollment under a symlinked parent
instead of failing capture by @jdx in
[#14871](#14871)
- **(e2e)** reap background watch process and retry isolated dir cleanup
by @jdx in [#14824](#14824)
- **(generate)** end install-script and task-stubs files with a newline
by @itochan in [#14819](#14819)
- **(github)** skip .netrc credentials on the asset reachability HEAD by
@jdx in [#14786](#14786)
- **(github)** page when mise-versions lists no releases for a repo by
@jdx in [#14877](#14877)
- **(gitlab)** ignore expired glab OAuth2 tokens instead of sending them
by @jdx in [#14873](#14873)
- **(http)** fall back to bundled root certificates when the system
store is empty by @jdx in
[#14817](#14817)
- **(http)** extract zip archives that contain read-only files on
Windows by @jdx in [#14869](#14869)
- **(install)** ignore curlrc write-out when downloading in install.sh
by @jdx in [#14830](#14830)
- **(install)** run [hooks].postinstall against the just-installed
version by @jdx in [#14853](#14853)
- **(java)** pick the newest build when installed versions differ only
after `+` by @jdx in [#14876](#14876)
- **(lock)** prefer the nearest lockfile when an unowned request is
ambiguous by @jdx in [#14818](#14818)
- **(lock)** accept PEP 691 +html content types from PyPI simple indexes
by @jdx in [#14852](#14852)
- **(lock)** keep a .config root's monorepo lockfile next to its config
by @jdx in [#14860](#14860)
- **(lockfile)** keep the Python a pipx tool selects by @jdx in
[#14794](#14794)
- **(oci)** package the rust toolchain in mise oci build by @jdx in
[#14854](#14854)
- **(packslip)** stay quiet about an installed version past the
release-age cutoff by @jdx in
[#14835](#14835)
- **(pipx)** find uv's Windows launcher for console scripts ending in
.py by @jdx in [#14825](#14825)
- **(prune)** resolve symlinked Python path in pypi receipts by @jdx in
[#14857](#14857)
- **(prune)** keep a selected Python reached through a minor-version
link by @jdx in [#14874](#14874)
- **(ruby)** don't fail gem installs when mise is not on PATH by @jdx in
[#14850](#14850)
- **(schema)** declare dotfile_groups entry keys and lint the schema
with Tombi by @jdx in [#14810](#14810)
- **(task)** let an empty run_windows skip the task on Windows by @jdx
in [#14859](#14859)
- **(task)** accept mise tasks list as an alias for ls by @jdx in
[#14878](#14878)
- **(unuse)** prune only the named version and say why one is kept by
@jdx in [#14863](#14863)

### 📚 Documentation

- **(dotfiles)** explain repo-only files, existing repos, and undoing an
accidental track by @jdx in
[#14829](#14829)
- **(dotfiles)** explain what add --no-apply, dot diff, and exclude do
by @jdx in [#14862](#14862)

### ⚡ Performance

- **(config)** check trusted_config_paths after cheaper trust rules by
@jdx in [#14875](#14875)

### 📦️ Dependency Updates

- update communique, hk, mr-boxington in mise.lock by @jdx in
[#14789](#14789)
- update jdx/workflows action to v1.1.2 by @renovate[bot] in
[#14792](#14792)
- update mise tools to latest by @renovate[bot] in
[#14793](#14793)
- update aube to v2.8.1 by @renovate[bot] in
[#14605](#14605)
- update rust crate sigstore-verify to 0.15 by @renovate[bot] in
[#14783](#14783)
- lock file maintenance by @renovate[bot] in
[#14777](#14777)
- update github actions by @renovate[bot] in
[#14796](#14796)
- lock file maintenance by @renovate[bot] in
[#14797](#14797)
- update rust crate serde-saphyr to v2 by @renovate[bot] in
[#14774](#14774)
- update node.js to v24.22.0 by @renovate[bot] in
[#14798](#14798)
- update rust crates by @renovate[bot] in
[#14755](#14755)
- update rust crate tokio to v1.54.1 by @jdx in
[#14849](#14849)
- update jdx crates to v7.1.1 by @renovate[bot] in
[#14861](#14861)

### 📦 Registry

- add goose-agent
([aqua:aaif-goose/goose](https://github.com/aaif-goose/goose)) by
@kwsantiago in [#14822](#14822)

### Ci

- retry windows-lint once and print diagnostics when it fails by @jdx in
[#14820](#14820)
- retry the docker image build in the bootstrap linux host test by @jdx
in [#14821](#14821)
- use jdx/workflows retry and gpg-import actions by @jdx in
[#14828](#14828)

### New Contributors

- @kwsantiago made their first contribution in
[#14822](#14822)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gem: tools fail to install when mise is not on PATH: the ruby's rubygems plugin calls mise reshim by name

1 participant