Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

`bundle install` exits 0 even when a git gem's submodules fail to clone

Aperta
#9,961 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@mattyb ci sta già lavorando.

Dal 21/10/2026.

  • #9962 di @mattyb — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
git, ruby
Ambito
backend, devtools

Direzione di ricerca

Start with Definition#setup_domain!, missing_specs?, and GitProxy#copy_to in the Bundler source, then trace the existing coverage for submodules: true and the check from #8539. Reproduce with the supplied script against an existing lockfile and an empty bundle path. Done when a failed submodule clone makes bundle install exit nonzero and the regression is covered by a spec.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Bundler
Describe the problem as clearly as you can

When a git gem uses submodules: true and its submodules can't be cloned, bundle install from an existing lockfile exits 0 and prints "Bundle complete!". The gem is left checked out without its submodules, and any native extension that needs them is never built. Nothing fails until the app requires the gem. For us this left a CI bundle cache with no grpc_c extension, and every build that restored it failed at boot.

Bisected between 2.7.1 (fails correctly) and 2.7.2 (exits 0) to #8925. Still reproduces on 4.0.0 and 4.1.0.beta2; the code is unchanged on master.

What I think happens:

  1. Since #8925, Definition#setup_domain! calls sources.cached! before install_needed?, so missing_specs? can now run git operations. On 4.x, preload_git_sources also checks out inside it.
  2. GitProxy#copy_to runs git reset --hard, then git submodule update --init --recursive, which raises GitCommandError.
  3. missing_specs? rescues it as a BundlerError and falls back to a remote resolve.
  4. requires_checkout? then asks GitProxy#installed_to?, which is true because reset --hard already filled the directory. The check from #8539 only covers a directory holding nothing but .git. So the checkout isn't retried and the install finishes.

A possible fix is to remove the destination in copy_to when the submodule update fails, then re-raise, so the half-finished checkout no longer counts as installed. I have a patch with a spec and can open a PR.

Did you try upgrading rubygems & bundler?

Yes, it reproduces on 4.1.0.beta2.

Post steps to reproduce the problem

Save as repro.sh and run ./repro.sh 4.1.0.beta2 (or 2.7.1 for comparison). It creates a gem whose submodule supplies lib's dependency, installs it once, makes the submodule URL unreachable, empties the bundle path and installs again from the lockfile.

#!/usr/bin/env bash
set -u
V="${1:?bundler version}"
gem install --no-document bundler -v "$V" >/dev/null

W="$(mktemp -d)"
cd "$W"
export GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=protocol.file.allow GIT_CONFIG_VALUE_0=always
export GIT_AUTHOR_NAME=x GIT_AUTHOR_EMAIL=x@x GIT_COMMITTER_NAME=x GIT_COMMITTER_EMAIL=x@x
export BUNDLE_PATH="$W/bundle" BUNDLE_GEMFILE="$W/app/Gemfile"

git init -q sub
echo 'SUB = :ok' > sub/sub.rb
git -C sub add . && git -C sub commit -qm sub

git init -q foo
cat > foo/foo.gemspec <<'RUBY'
Gem::Specification.new do |s|
  s.name = "foo"
  s.version = "1.0"
  s.summary = "foo"
  s.authors = ["x"]
  s.files = Dir["lib/**/*"]
end
RUBY
mkdir -p foo/lib
echo 'require_relative "../vendor/sub/sub"' > foo/lib/foo.rb
git -C foo submodule add -q "file://$W/sub" vendor/sub
git -C foo add . && git -C foo commit -qm foo

mkdir app
cat > app/Gemfile <<RUBY
source "https://rubygems.org"
gem "foo", git: "file://$W/foo", submodules: true
RUBY

bundle "_${V}_" install >/dev/null 2>&1
echo "--- first install: exit $?"

mv sub sub-unreachable
rm -rf bundle

bundle "_${V}_" install --retry 0 >install.log 2>&1
echo "--- install with unreachable submodule: exit $? ($(tail -n 1 install.log))"
bundle "_${V}_" exec ruby -e 'require "foo"; puts "require foo: ok"' 2>&1 | grep -m1 -oE 'require foo: ok|cannot load such file -- [^ ]+'
Which command did you run?

bundle install with a lockfile in place and an empty bundle path.

What were you expecting to happen?

bundle install fails with the git submodule update error and a non-zero exit, as on 2.7.1:

--- first install: exit 0
--- install with unreachable submodule: exit 11 (Failed to clone 'vendor/sub' a second time, aborting)
What happened instead?
--- first install: exit 0
--- install with unreachable submodule: exit 0 (Bundled gems are installed into `./bundle`)
cannot load such file -- /tmp/tmp.XXXX/bundle/ruby/4.0.0/bundler/gems/foo-891597d9e44e/vendor/sub/sub
If not included with the output of your command, run bundle env and paste the output below

Ruby 4.0.7, RubyGems 4.0.20, git 2.55, Linux x86_64. Same result with Bundler 2.7.2, 4.0.0 and 4.1.0.beta2; 2.7.1 fails correctly.

Lingua principale
Ruby
Stelle
4k
Fork
1.9k
Merge medio
1g 4h
PR unite (30g)
36

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di ruby/rubygems

Tutte le issue di ruby/rubygems

Issue simili

Altre issue su Ruby

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.