Range pin in devEngines.packageManager records the running pnpm in the lockfile without checking minimumReleaseAge, so switching to it fails for everyone else
Verify latest release
- I verified that the issue exists in the latest pnpm release
pnpm version
No response
Which area(s) of pnpm are affected? (leave empty if unsure)
No response
Link to the code that reproduces this issue or a replay of the bug
No response
Reproduction steps
package.json:
{
"devEngines": {
"packageManager": {
"name": "pnpm",
"version": "^12.7.0",
"onFail": "download"
}
}
}pnpm-workspace.yaml:
minimumReleaseAge: 4320 # 3 daysOutside the project, make pnpm 12.8.1 the global pnpm (
pnpm self-update 12.8.1). The global install doesn't use the project's settings, which is expected.In the project, remove
node_modulesandpnpm-lock.yamland runpnpm install. It succeeds and writes this, with no warning or prompt about release age:packageManagerDependencies: pnpm: specifier: ^12.7.0 version: 12.8.1Nothing fails yet: the running pnpm is the locked version, so there is nothing to download.
Simulate another contributor or CI. Outside the project, switch the global pnpm to a different version that still satisfies the range (
pnpm self-update 12.7.0), and empty$PNPM_HOME/package-manager-storeso 12.8.1 isn't cached.In the project, run:
$ CI=true pnpm install --frozen-lockfile Error: ERR_PNPM_NO_MATURE_MATCHING_VERSION × adding a new package ╰─▶ 15 versions do not meet the minimumReleaseAge constraint: @pnpm/[email protected] was published at 2026-09-28T17:38:06.259Z, within the minimumReleaseAge cutoff (2026-09-27T12:01:01.750Z) ... [email protected] was published at 2026-09-28T17:38:17.288Z, within the minimumReleaseAge cutoff (2026-09-27T12:01:01.750Z)(exit code 1)
pnpm --versiononly warns and keeps running 12.7.0:[WARN] Cannot use the pnpm version this project pins: ERR_PNPM_NO_MATURE_MATCHING_VERSION: adding a new package: 15 versions do not meet the minimumReleaseAge constraint: ... Run the install interactively to approve these picks, add them to minimumReleaseAgeExclude in pnpm-workspace.yaml, or wait for the packages to mature. 12.7.0
Describe the Bug
When the pin is a range, package_manager_to_sync (pnpm/crates/cli/src/cli_args/package_manager.rs) records the running pnpm's version in packageManagerDependencies whenever it satisfies the range:
// A range pin names no exact version, so the running pnpm's version is
// the one the project actually uses.
version_satisfies(PNPM_VERSION, wanted_version)
.then(|| PackageManagerToSync { ... version: PNPM_VERSION.to_string() })This runs on every command. Because is_package_manager_resolved compares against the running version, pnpm also overwrites a locked version that already satisfies the range. In our repo, a mature 12.7.0 entry was replaced with 12.8.1 this way. Nothing checks the running version against the project's minimumReleaseAge.
It's fine that the global pnpm was installed without the project's cutoff. The problem is that the project then adopts that version into its lockfile unchecked. The switch to the locked version does apply the project's release-age settings; #16323 keeps them deliberately. So one contributor with a newer global pnpm writes a version into the lockfile that nobody else can install until the cutoff passes. Reverting the lockfile only helps until that contributor runs their next command.
[!IMPORTANT] Updating the global pnpm to the latest release makes the error go away, but it doesn't fix anything. The latest global pnpm is the same version the lockfile records, so pnpm never has to switch or download a pinned pnpm, and the
minimumReleaseAgecheck never runs. That is why the contributor who wrote the lockfile never sees the problem. It only shows up for people and CI jobs running a different pnpm version.
Related: #15396, #16323, #10699
Expected Behavior
The version pnpm writes to packageManagerDependencies should follow the same minimumReleaseAge rules as the switch that installs it. When the running pnpm is younger than the cutoff, pnpm could keep the locked version if it still satisfies the range. Otherwise it could resolve the newest mature version in the range. At minimum, it should warn or prompt the way a regular install does for an immature dependency, instead of recording the version silently.
Which Node.js version are you using?
26.10.0
Which operating systems have you used?
- macOS
- Windows
- Linux
If your OS is a Linux based, which distribution are you using?
No response
Source: pnpm/pnpm