Skip to content

bundle update conservative - cooldown error cause of non-changed gem #9613

@senid231

Description

@senid231

Describe the problem as clearly as you can

When a source has a cooldown set (e.g. source "https://rubygems.org", cooldown: 7),
Bundler excludes versions published inside the cooldown window from the candidate set
for every gem during resolution — including a version that is already pinned in
Gemfile.lock
.

As a result, a gem whose only published versions are all younger than the cooldown
window (no older fallback) has an empty candidate set the moment resolution has to
re-evaluate it. Even though one of those cooled versions is already locked and installed,
Bundler refuses to keep it and fails:

Could not find gems matching 'anyway_app_config (~> 0.3)' valid for all
resolution platforms (...) in rubygems repository https://rubygems.org/
or installed locally.

The source contains the following gems matching 'anyway_app_config (~> 0.3)':
  * anyway_app_config-0.3.1
  * anyway_app_config-0.3.2

2 versions excluded by the cooldown setting; pass `--cooldown 0` to bypass.

This breaks unrelated operations. Updating some other gem (bundle lock --update sentry-rails --conservative) fails purely because a fresh, unrelated gem in the lock
gets re-evaluated and has no non-cooled version to land on. --conservative does not
help — the cooldown filter removes the locked version from the candidate set, so Bundler
cannot even retain it.

Expected: a version already present in Gemfile.lock should stay selectable regardless
of cooldown. The cooldown window is about adopting new versions; it should not retract
a version the lockfile has already adopted, and should not make an unrelated update
impossible without BUNDLE_COOLDOWN=0.

(Practical impact: any CI/automation that regenerates the lockfile — e.g. Renovate —
fails on every update for the ~7 days it takes a freshly published gem to age out, if
that gem has no older release to fall back to.)

Did you try upgrading rubygems & bundler?

Yes. Reproduced on the latest at time of writing — Bundler 4.0.14, RubyGems 3.6.9,
Ruby 3.4.9.

Post steps to reproduce the problem

Two conditions are required:

  1. A gem in the lockfile whose entire set of published versions matching the
    requirement is inside the cooldown window (i.e. no older version exists to fall back
    to). A brand-new gem/line works well.
  2. An operation that forces that gem to be re-resolved rather than kept — in
    practice a --update of another gem that shares part of the graph, a major-version
    bump, or any change that pushes Bundler into a from-scratch resolution.

NOTE on minimization: in a small project (2–4 gems) Bundler resolves the cooled gem
incrementally and keeps the already-locked cooled version, so the failure does NOT
show — even with the exact same gems, constraint bumps, all target platforms, a clean
install path, or git-source gems present. The failure requires a dependency graph
large enough that the major-version bump forces a from-scratch re-resolution, which
re-picks the cooled gem from the (now empty) cooldown-filtered candidate set instead of
retaining the lock entry. We could not reduce this below the real ~200-gem lockfile.
Git-source gems were ruled out in both directions (removing all of them still fails;
adding one to a small repro still succeeds). The example gem also ages out of the
7-day window ~1 week after publish, after which it stops reproducing entirely.

Dockerfile sketch (replace the example gem with any gem that currently has only
versions published in the last 7 days):

FROM ruby:3.4
RUN gem update --system
WORKDIR /app
# A Gemfile whose source has a cooldown and that includes a gem with only fresh versions
COPY Gemfile Gemfile.lock ./
# Lockfile was generated with BUNDLE_COOLDOWN=0 so the fresh gem is pinned + installed.
# Now run a normal (cooldown-enforcing) update of an unrelated gem that forces re-resolve:
CMD ["bundle", "lock", "--update", "<unrelated-gem>", "--conservative"]

Which command did you run?

bundle lock --update sentry-rails --conservative

(any update that re-resolves the cooled gem; bundle install / bundle lock after a
graph-invalidating Gemfile change reproduce it too)

What were you expecting to happen?

The unrelated update succeeds, retaining the already-locked version of the cooled gem
(it's already in the lockfile and installed). Cooldown should only prevent upgrading to
a newer cooled version, not invalidate an already-adopted one.

What happened instead?

Writing lockfile to .../Gemfile.lock
Fetching gem metadata from https://rubygems.org/........
Could not find gems matching 'anyway_app_config (~> 0.3)' valid for all
resolution platforms (aarch64-linux, aarch64-linux-gnu, aarch64-linux-musl,
arm-linux-gnu, arm-linux-musl, arm64-darwin, x86_64-darwin, x86_64-linux,
x86_64-linux-gnu, x86_64-linux-musl) in rubygems repository
https://rubygems.org/ or installed locally.

The source contains the following gems matching 'anyway_app_config (~> 0.3)':
  * anyway_app_config-0.3.1
  * anyway_app_config-0.3.2

2 versions excluded by the cooldown setting; pass `--cooldown 0` to bypass.

Exit code 7. Passing BUNDLE_COOLDOWN=0 makes the same command succeed.

bundle env

Bundler   4.0.14
RubyGems  3.6.9
Ruby      3.4.9 (2026-03-11 revision 76cca827ab) +PRISM [x86_64-linux]
Platform  x86_64-linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions