ruby/rubygems · error · RubyVersionMismatch

Your Ruby version is #{actual}, but your Gemfile specified #

Error message

Your Ruby version is #{actual}, but your Gemfile specified #{expected}

What it means

Definition#validate_ruby! (reached via validate_runtime! when the definition materializes during install, setup or exec) compares the running interpreter against the Gemfile ruby directive; on mismatch it raises Bundler::RubyVersionMismatch showing actual versus expected versions, with engine and engine_version variants (lib/bundler/definition.rb:520). The Gemfile pins the required runtime; the current process violates that pin for the plain version or for the engine constraint.

Source

Thrown at lib/bundler/definition.rb:520

      validate_platforms!
    end

    def validate_ruby!
      return unless ruby_version

      if diff = ruby_version.diff(Bundler::RubyVersion.system)
        problem, expected, actual = diff

        msg = case problem
              when :engine
                "Your Ruby engine is #{actual}, but your Gemfile specified #{expected}"
              when :version
                "Your Ruby version is #{actual}, but your Gemfile specified #{expected}"
              when :engine_version
                "Your #{Bundler::RubyVersion.system.engine} version is #{actual}, but your Gemfile specified #{ruby_version.engine} #{expected}"
        end

        raise RubyVersionMismatch, msg
      end
    end

    def validate_platforms!
      return if current_platform_locked? || @platforms.include?(Gem::Platform::RUBY)

      raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
        "but your local platform is #{Bundler.local_platform}. " \
        "Add the current platform to the lockfile with\n`bundle lock --add-platform #{Bundler.local_platform}` and try again."
    end

    def normalize_platforms
      resolve.normalize_platforms!(current_dependencies, platforms)

      @resolve = SpecSet.new(resolve.for(current_dependencies, @platforms))
    end

    def add_platform(platform)

View on GitHub (pinned to 86cbb817a3)

Solutions

  1. Switch to the required ruby: `rbenv install 3.2.2 && rbenv local 3.2.2`, or the rvm or asdf equivalent
  2. Compare `ruby -v` with the RUBY VERSION line in Gemfile.lock to confirm which side is stale
  3. If the pin itself is wrong, update the Gemfile ruby directive and .ruby-version to the intended version, then `bundle install`
  4. Align CI and Docker toolchains with the pin, for example FROM ruby:3.2.2

Example fix

# before
# Gemfile: ruby "3.3.0"; shell has ruby 3.1.4
$ bundle install
# => Your Ruby version is 3.1.4, but your Gemfile specified 3.3.0

# after
$ rbenv install 3.3.0 && rbenv local 3.3.0
$ bundle install
Defensive patterns

Strategy: validation

Validate before calling

required = Bundler.definition.ruby_version
if required && !required.satisfied_by?(Bundler::RubyVersion.system)
  abort "wrong ruby #{RUBY_VERSION}; project requires #{required}"
end

Try / catch

begin
  Bundler.definition.validate_runtime!
rescue Bundler::RubyVersionMismatch => e
  abort "switch ruby: #{e.message}"
end

Prevention

When it happens

Trigger: Gemfile declares `ruby "3.2.2"` but the active toolchain is 3.1.4 (rbenv/rvm/asdf local mismatch); CI uses a ruby:3.1 image while the Gemfile pins 3.3; engine directives like `ruby "...", engine: "jruby"` executed under MRI; cron or Docker entrypoints that bypass version managers and land on system ruby.

Common situations: A teammate bumped the pin and the local ruby was never installed; .ruby-version not honored because rbenv or direnv is not initialized in the shell; CI base image drift; running bundle with a different ruby than the app server.

Related errors


AI-assisted analysis of ruby/rubygems@86cbb817a3 (2026-08-23). Data as JSON: /api/errors/fae1c9bc54befc7b. Report an issue: GitHub.