Summary
Renovate implements the preset's minimumReleaseAge: "7 days" by passing npm
--before <cutoff>. When the repository's existing package-lock.json already
contains packages published after that cutoff, Renovate cannot enforce
--before, drops it silently, and proposes latest anyway — while still
posting renovate/stability-days: success.
Every UI repo's .npmrc sets min-release-age=7, so npm then refuses to
resolve what Renovate proposed. The lockfile refresh fails with ETARGET,
renovate/artifacts reports only "Artifact file update failure" with no
detail, the PR carries a package.json bump with no package-lock.json,
and every job that runs npm ci fails. The PR cannot go green until the
version ages past npm's cutoff and someone rebases it.
Renovate states the cause itself, but only in the Dependency Dashboard —
neither the PR nor the failing job log mentions it (niac-go#1257):
⚠️ WARN: npm --before could not be enforced because existing locked
packages were published after the minimumReleaseAge cutoff. This will
resolve after the next lock file maintenance run.
Evidence
Four niac-go PRs opened 2026-09-07 and still red on 2026-09-09:
#1874 #1875 #1876 #1877. Age of the proposed version at PR creation, against
the 7-day policy:
| PR |
package |
version |
published |
age at PR |
| #1874 |
@chromatic-com/storybook |
5.3.1 |
2026-09-02 13:43Z |
5.04 d |
| #1876 |
postcss |
8.5.28 |
2026-09-03 15:14Z |
3.97 d |
| #1877 |
@biomejs/biome |
2.5.12 |
2026-09-03 07:25Z |
4.30 d |
Reproduced locally in a clean worktree off niac-go main (node 26.8.1,
npm 12.0.2), which is what Renovate's lockfile refresh runs:
$ npm install --package-lock-only # main, unmodified
up to date, audited 456 packages in 662ms
$ # bump @chromatic-com/storybook 5.3.0 -> 5.3.1, then:
$ npm install --package-lock-only
npm error code ETARGET
npm error notarget No matching version found for @chromatic-com/storybook@5.3.1
with a date before 9/2/2026, 5:26:56 AM.
Each branch has a single commit, so this is not an in-place update of a branch
opened when an older, eligible version was current. Most PRs are unaffected —
8 of 12 recent dependency PRs across seed/stem/niac-go/trellis were created at
exactly ≥ 7.00 d — so the preset is honoured until this fallback fires.
lint-staged@17.5.0 was proposed at 3.0 d in three repos on the same tick.
Impact
Each occurrence produces a PR that is born red, burns a full CI run per repo,
and parks against the drivers' "clear red bot PRs" rule until a human notices.
The .npmrc comment calls the two settings load-bearing and says they "MUST
stay equal" — they are equal, and the pairing still fails, because one side
gives up quietly.
What not to do
Raising minimumReleaseAge above 7 days does not help: the fallback drops the
constraint entirely rather than shortening it.
Options
- Keep
lock-file-maintenance frequent enough that the lockfile never holds
packages newer than the cutoff (it runs and merges in every repo today —
niac-go#1938 merged 2026-09-08 — but the window between a lockfile refresh
and the next dependency tick is where this fires).
- Make the failure loud: have the drivers read the Dependency Dashboard
warning block, since the PR and job log both omit the cause.
- Ask upstream whether
--before unenforceability should skip the update
rather than fall through to latest.
Summary
Renovate implements the preset's
minimumReleaseAge: "7 days"by passing npm--before <cutoff>. When the repository's existingpackage-lock.jsonalreadycontains packages published after that cutoff, Renovate cannot enforce
--before, drops it silently, and proposes latest anyway — while stillposting
renovate/stability-days: success.Every UI repo's
.npmrcsetsmin-release-age=7, so npm then refuses toresolve what Renovate proposed. The lockfile refresh fails with
ETARGET,renovate/artifactsreports only "Artifact file update failure" with nodetail, the PR carries a
package.jsonbump with nopackage-lock.json,and every job that runs
npm cifails. The PR cannot go green until theversion ages past npm's cutoff and someone rebases it.
Renovate states the cause itself, but only in the Dependency Dashboard —
neither the PR nor the failing job log mentions it (niac-go#1257):
Evidence
Four niac-go PRs opened 2026-09-07 and still red on 2026-09-09:
#1874 #1875 #1876 #1877. Age of the proposed version at PR creation, against
the 7-day policy:
@chromatic-com/storybookpostcss@biomejs/biomeReproduced locally in a clean worktree off
niac-gomain(node 26.8.1,npm 12.0.2), which is what Renovate's lockfile refresh runs:
Each branch has a single commit, so this is not an in-place update of a branch
opened when an older, eligible version was current. Most PRs are unaffected —
8 of 12 recent dependency PRs across seed/stem/niac-go/trellis were created at
exactly ≥ 7.00 d — so the preset is honoured until this fallback fires.
lint-staged@17.5.0was proposed at 3.0 d in three repos on the same tick.Impact
Each occurrence produces a PR that is born red, burns a full CI run per repo,
and parks against the drivers' "clear red bot PRs" rule until a human notices.
The
.npmrccomment calls the two settings load-bearing and says they "MUSTstay equal" — they are equal, and the pairing still fails, because one side
gives up quietly.
What not to do
Raising
minimumReleaseAgeabove 7 days does not help: the fallback drops theconstraint entirely rather than shortening it.
Options
lock-file-maintenancefrequent enough that the lockfile never holdspackages newer than the cutoff (it runs and merges in every repo today —
niac-go#1938 merged 2026-09-08 — but the window between a lockfile refresh
and the next dependency tick is where this fires).
warning block, since the PR and job log both omit the cause.
--beforeunenforceability should skip the updaterather than fall through to latest.