Describe the problem
Bundler installs a regular copy of a gem even when the exact same version is already available as a Ruby default gem.
This appears to be the same underlying behavior reported in #8180. That issue was closed by #8412, but #8412 specifically fixes the behavior when --prefer-local is used. With a normal bundle install, the behavior is still reproducible with Bundler 4.0.18.
In my case this was initially exposed by Ruby LSP, whose generated lockfile referenced io-console 0.8.2. Ruby 4.0.6 already ships io-console 0.8.2 as a default gem, but Bundler downloaded, built, and installed an additional regular copy of io-console 0.8.2.
The issue is reproducible without Ruby LSP.
Environment
> ruby -v
ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +PRISM [x64-mingw-ucrt]
> gem -v
4.0.18
Before the test, io-console 0.8.2 is present only as a default gem:
io-console-0.8.2 | DEFAULT | c:/ruby-4.0.6-x64/lib/ruby/gems/4.0.0/specifications/default/io-console-0.8.2.gemspec
Minimal reproduction
Create a new directory with this Gemfile:
source "https://rubygems.org"
gem "io-console", "0.8.2"
Generate the lockfile:
Then run:
Observed output:
Running `bundle install --verbose` with bundler 4.0.18
Found no changes, using resolution from the lockfile
Using bundler 4.0.18
0: bundler (4.0.18) from c:/ruby-4.0.6-x64/lib/ruby/gems/4.0.0/specifications/default/bundler-4.0.18.gemspec
HTTP GET https://index.rubygems.org/versions
HTTP 304 Not Modified https://index.rubygems.org/versions
Fetching gem metadata from https://rubygems.org/
Looking up gems ["io-console"]
Fetching io-console 0.8.2
Downloaded io-console in: 0.086s
Installing io-console 0.8.2 with native extensions
Temporarily enhancing PATH for MSYS/MINGW...
Building native extensions. This could take a while...
Installed io-console in: 18.301s
0: io-console (0.8.2) from c:/ruby-4.0.6-x64/lib/ruby/gems/4.0.0/specifications/default/io-console-0.8.2.gemspec
Bundle complete! 1 Gemfile dependency, 1 gem now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Afterwards, both specifications exist:
io-console-0.8.2 | NORMAL | c:/ruby-4.0.6-x64/lib/ruby/gems/4.0.0/specifications/io-console-0.8.2.gemspec
io-console-0.8.2 | DEFAULT | c:/ruby-4.0.6-x64/lib/ruby/gems/4.0.0/specifications/default/io-console-0.8.2.gemspec
So Bundler downloads, compiles, and installs a regular copy of the exact version that is already available as a default gem.
Interestingly, the verbose output then reports the default-gem specification as the one being used:
0: io-console (0.8.2) from c:/ruby-4.0.6-x64/lib/ruby/gems/4.0.0/specifications/default/io-console-0.8.2.gemspec
--prefer-local behaves as expected
After removing the redundant regular copy and restoring the initial state, running:
bundle install --verbose --prefer-local
does not reinstall the gem:
Running `bundle install --prefer-local --verbose` with bundler 4.0.18
Found no changes, using resolution from the lockfile
Using bundler 4.0.18
0: bundler (4.0.18) from c:/ruby-4.0.6-x64/lib/ruby/gems/4.0.0/specifications/default/bundler-4.0.18.gemspec
Using io-console 0.8.2
0: io-console (0.8.2) from c:/ruby-4.0.6-x64/lib/ruby/gems/4.0.0/specifications/default/io-console-0.8.2.gemspec
Bundle complete! 1 Gemfile dependency, 1 gem now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Expected behavior
For a normal bundle install, if the exact required name and version are already available as a default gem, I would expect Bundler to use that default gem rather than download and install an identical regular copy.
This matters in particular for default gems with native extensions: in this example the unnecessary installation recompiles io-console.
Related issues
Since the original #8180 reproducer did not use --prefer-local, is the current behavior of plain bundle install intentional? If not, #8180 appears to remain reproducible in Bundler 4.0.18.
Describe the problem
Bundler installs a regular copy of a gem even when the exact same version is already available as a Ruby default gem.
This appears to be the same underlying behavior reported in #8180. That issue was closed by #8412, but #8412 specifically fixes the behavior when
--prefer-localis used. With a normalbundle install, the behavior is still reproducible with Bundler 4.0.18.In my case this was initially exposed by Ruby LSP, whose generated lockfile referenced
io-console 0.8.2. Ruby 4.0.6 already shipsio-console 0.8.2as a default gem, but Bundler downloaded, built, and installed an additional regular copy ofio-console 0.8.2.The issue is reproducible without Ruby LSP.
Environment
Before the test,
io-console 0.8.2is present only as a default gem:Minimal reproduction
Create a new directory with this
Gemfile:Generate the lockfile:
bundle lockThen run:
bundle install --verboseObserved output:
Afterwards, both specifications exist:
So Bundler downloads, compiles, and installs a regular copy of the exact version that is already available as a default gem.
Interestingly, the verbose output then reports the default-gem specification as the one being used:
--prefer-localbehaves as expectedAfter removing the redundant regular copy and restoring the initial state, running:
bundle install --verbose --prefer-localdoes not reinstall the gem:
Expected behavior
For a normal
bundle install, if the exact required name and version are already available as a default gem, I would expect Bundler to use that default gem rather than download and install an identical regular copy.This matters in particular for default gems with native extensions: in this example the unnecessary installation recompiles
io-console.Related issues
bundle installinstalls default gems again even when the required versions are already provided by Ruby.--prefer-localnot respecting default gems #8412 closed bundle install with default gems already installed in ruby tries to install them again #8180 by making default gems preferred when--prefer-localis used.Since the original #8180 reproducer did not use
--prefer-local, is the current behavior of plainbundle installintentional? If not, #8180 appears to remain reproducible in Bundler 4.0.18.