Describe the problem as clearly as you can
When Ruby is installed via mise (or any setup that compiles Ruby with --enable-load-relative), running bundle exec <command> fails with:
No such file or directory - <command> (Errno::ENOENT)
This happens when BUNDLE_PATH is set to vendor/bundle (e.g. via bundle config set path vendor/bundle).
Root cause
When Ruby is built with --enable-load-relative, RubyGems generates binstubs with a #!/bin/sh wrapper instead of #!/usr/bin/env ruby:
#!/bin/sh
# -*- ruby -*-
_=_\
=begin
bindir="${0%/*}"
exec "$bindir/ruby" "-x" "$0" "$@"
=end
When BUNDLE_PATH=vendor/bundle, Bundler::SharedHelpers#set_path prepends vendor/bundle/ruby/X.Y.Z/bin to PATH. During bundle exec, Bundler.which finds the binstub under that vendor bin directory first. Because its shebang is #!/bin/sh, ruby_shebang? returns false and Bundler falls back to Kernel.exec. The OS then runs the shell wrapper, which tries to find ruby at $bindir/ruby — i.e. inside vendor/bundle/.../bin/ — where no ruby binary exists, and the command fails.
Steps to reproduce
- Install Ruby via mise (or compile Ruby with
--enable-load-relative)
- Create a Rails (or any Bundler-managed) project with a
bin/ directory containing binstubs (e.g. bin/rails)
- Configure
BUNDLE_PATH=vendor/bundle:
bundle config set path vendor/bundle
- Run
bundle install
- Run
bundle exec rails (or any binstubbed command)
What were you expecting to happen?
bundle exec rails should run successfully.
What happened instead?
Errno::ENOENT: No such file or directory - rails
Why the project bin/ directory fixes it
Project binstubs under bin/ (generated by bundle binstubs) use #!/usr/bin/env ruby, so ruby_shebang? returns true and Bundler uses load-based execution instead of falling back to kernel_exec. Prepending the project bin/ to PATH before the vendor bin path ensures Bundler.which finds the correct binstub first.
Environment
$ mise --version
# (any recent version)
$ ruby --version
# Ruby built with --enable-load-relative
$ bundle --version
# Bundler 2.x or later
$ bundle config path
# vendor/bundle
Related
Describe the problem as clearly as you can
When Ruby is installed via mise (or any setup that compiles Ruby with
--enable-load-relative), runningbundle exec <command>fails with:This happens when
BUNDLE_PATHis set tovendor/bundle(e.g. viabundle config set path vendor/bundle).Root cause
When Ruby is built with
--enable-load-relative, RubyGems generates binstubs with a#!/bin/shwrapper instead of#!/usr/bin/env ruby:When
BUNDLE_PATH=vendor/bundle,Bundler::SharedHelpers#set_pathprependsvendor/bundle/ruby/X.Y.Z/bintoPATH. Duringbundle exec,Bundler.whichfinds the binstub under that vendor bin directory first. Because its shebang is#!/bin/sh,ruby_shebang?returnsfalseand Bundler falls back toKernel.exec. The OS then runs the shell wrapper, which tries to findrubyat$bindir/ruby— i.e. insidevendor/bundle/.../bin/— where norubybinary exists, and the command fails.Steps to reproduce
--enable-load-relative)bin/directory containing binstubs (e.g.bin/rails)BUNDLE_PATH=vendor/bundle:bundle installbundle exec rails(or any binstubbed command)What were you expecting to happen?
bundle exec railsshould run successfully.What happened instead?
Why the project
bin/directory fixes itProject binstubs under
bin/(generated bybundle binstubs) use#!/usr/bin/env ruby, soruby_shebang?returnstrueand Bundler usesload-based execution instead of falling back tokernel_exec. Prepending the projectbin/toPATHbefore the vendor bin path ensuresBundler.whichfinds the correct binstub first.Environment
Related
--enable-load-relativebinstub issue: Binstub installation conflicts when ruby configured with--enable-load-relative#2955