← Debugging Guides

阅读中文版本

Bundler Frozen Mode — Gemfile.lock Would Change

Fix "frozen mode" Bundler errors by resolving the lockfile mismatch locally, committing Gemfile.lock, and understanding bundle config frozen.

intermediatedebuggingrubybundlerdependencies

Symptoms

  • bundle install fails with "you are trying to install in deployment mode ... would have changed"
  • CI fails but local install works
  • The error mentions Gemfile.lock would change

Possible causes

  • Gemfile and Gemfile.lock are out of sync (a gem was added without updating the lock)
  • The lockfile is missing or not committed, so deployment mode has nothing to verify
  • bundle config frozen/deployment is set, forbidding lockfile writes

Diagnosis steps

Resolve the lockfile locally

bundle install && git add Gemfile.lock && git commit -m "update lockfile"

Interpretation

Updating the lock locally then committing makes deployment mode find a consistent lock.

Inspect the frozen setting

bundle config list | grep -i frozen

Interpretation

If frozen is true, CI forbids any lockfile change; the fix is to commit the correct lock, not disable frozen.

Root cause

In frozen/deployment mode Bundler refuses to modify Gemfile.lock. If the Gemfile and lock disagree, or the lock is absent, installation cannot proceed because respecting the lock would require a change.

Fix

Run bundle install without frozen locally to regenerate Gemfile.lock, commit it, and ensure deployment keeps frozen on so CI is reproducible.

Risk note

Disabling frozen to force a deploy produces non-reproducible builds; never turn it off merely to pass CI.

Verify the fix

Run bundle install --frozen in a clean checkout and confirm it succeeds without changing the lock; assert bundle check passes.

Symptoms

This guide profiles the failure behind “Bundler Frozen Mode — Gemfile.lock Would Change”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.

Observed symptoms include:

  • bundle install fails with “you are trying to install in deployment mode … would have changed”
  • CI fails but local install works
  • The error mentions Gemfile.lock would change

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Resolve the lockfile locally

bundle install && git add Gemfile.lock && git commit -m "update lockfile"

Updating the lock locally then committing makes deployment mode find a consistent lock.

Step 2: Inspect the frozen setting

bundle config list | grep -i frozen

If frozen is true, CI forbids any lockfile change; the fix is to commit the correct lock, not disable frozen.

Likely contributors, in order of frequency:

  • Gemfile and Gemfile.lock are out of sync (a gem was added without updating the lock)
  • The lockfile is missing or not committed, so deployment mode has nothing to verify
  • bundle config frozen/deployment is set, forbidding lockfile writes

Root Cause

In frozen/deployment mode Bundler refuses to modify Gemfile.lock. If the Gemfile and lock disagree, or the lock is absent, installation cannot proceed because respecting the lock would require a change.

The Fix

Run bundle install without frozen locally to regenerate Gemfile.lock, commit it, and ensure deployment keeps frozen on so CI is reproducible.

Watch out: Disabling frozen to force a deploy produces non-reproducible builds; never turn it off merely to pass CI.

# local: regenerate and commit the lock
bundle install
bundle lock --update
git add Gemfile.lock && git commit -m "sync Gemfile.lock"

# CI/deploy: keep frozen to guarantee reproducibility
bundle config set --local deployment true
bundle config set --local frozen true
bundle install --frozen

Verify and Prevent

Run bundle install –frozen in a clean checkout and confirm it succeeds without changing the lock; assert bundle check passes.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.