Skip to content

bundle exec fails with "No such file or directory" when using load-relative Ruby (mise) with BUNDLE_PATH=vendor/bundle #9495

@masak1yu

Description

@masak1yu

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

  1. Install Ruby via mise (or compile Ruby with --enable-load-relative)
  2. Create a Rails (or any Bundler-managed) project with a bin/ directory containing binstubs (e.g. bin/rails)
  3. Configure BUNDLE_PATH=vendor/bundle:
    bundle config set path vendor/bundle
    
  4. Run bundle install
  5. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions