ruby/rubygems · error · ProductionError
can't be updated because frozen mode is set If this is a de
Error message
can't be updated because frozen mode is set
If this is a development machine, remove the #{SharedHelpers.relative_lockfile_path} freeze by running `#{suggested_command}`. What it means
The companion frozen check in ensure_equivalent_gemfile_and_lockfile: a lockfile exists but lockfile_changes_summary reports drift between Gemfile and Gemfile.lock, so bundler raises ProductionError with the diff and, when the frozen setting came from local config rather than the environment, appends how to lift the freeze (lib/bundler/definition.rb:497). Under frozen mode the Gemfile is the contract and the lockfile must already satisfy it; this is bundler's equivalent of npm ci refusing an out-of-sync lockfile. It fires during install, Bundler.setup and inject.
Source
Thrown at lib/bundler/definition.rb:497
end
def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
return unless Bundler.frozen_bundle?
raise ProductionError, "Frozen mode is set, but there's no lockfile" unless lockfile_exists?
msg = lockfile_changes_summary("frozen mode is set")
return unless msg
unless explicit_flag
suggested_command = unless Bundler.settings.locations("frozen").keys.include?(:env)
"bundle config set frozen false"
end
msg << "\n\nIf this is a development machine, remove the #{SharedHelpers.relative_lockfile_path} " \
"freeze by running `#{suggested_command}`." if suggested_command
end
raise ProductionError, msg
end
def validate_runtime!
validate_ruby!
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}"View on GitHub (pinned to 86cbb817a3)
Solutions
- Regenerate the lockfile where writes are allowed: `bundle install`, commit Gemfile.lock, then retry the frozen environment
- If this machine may lock, unfreeze: `bundle config set frozen false` or unset BUNDLE_FROZEN
- Read the diff in the error, or run `bundle lock --check`, to see exactly which dependencies drifted
- Add `bundle lock --check` as a PR check so drift fails before deploy
Example fix
# before # Gemfile: gem "sidekiq", "~> 7.0" changed to "~> 7.3" without re-locking $ BUNDLE_FROZEN=true bundle install # => can't be updated because frozen mode is set # after $ bundle install # dev machine re-locks $ git commit -am "bump sidekiq and lockfile" $ BUNDLE_FROZEN=true bundle install # succeeds
Defensive patterns
Strategy: validation
Validate before calling
# pre-deploy gate
bundle lock --check || {
echo "Gemfile and Gemfile.lock out of sync under frozen mode" >&2
exit 1
} Prevention
- Commit Gemfile and Gemfile.lock changes together
- Keep frozen scoped to deploy and CI
- Fail PRs with bundle lock --check instead of discovering drift at deploy time
When it happens
Trigger: `bundle install` with BUNDLE_FROZEN=true after adding or changing a dependency in the Gemfile without re-locking; `bundle exec` or Bundler.setup under frozen with a stale lockfile; a PR edited the Gemfile but the deploy uses an old Gemfile.lock because only one of the two files was committed.
Common situations: Deploy pipelines with frozen enabled; `bundle config set frozen true` left over on a dev machine so every Gemfile edit fails the next install; BUNDLE_FROZEN baked into a base Docker image.
Related errors
- Your lockfile needs to be updated, but it can't be because f
- Frozen mode is set, but there's no lockfile
- This Bundle hasn't been installed yet. Run `bundle install`
- #{gemfile} not found
- can't be updated because file system is read-only
AI-assisted analysis of ruby/rubygems@86cbb817a3 (2026-08-23).
Data as JSON: /api/errors/0ef896b110812fcd.
Report an issue: GitHub.