Skip to content

fix(apply): hold packages with a version-pinned pnpm patch - #176

Merged
donfear merged 2 commits into
mainfrom
fix/pnpm-pinned-patch-hold
Oct 10, 2026
Merged

donfear merged 2 commits into
mainfrom
fix/pnpm-pinned-patch-hold

Conversation

@donfear

@donfear donfear commented Oct 10, 2026

Copy link
Copy Markdown
Owner

Problem

Running the GitHub Action (or inup --apply) on a pnpm project that patches a dependency at an exact version fails the whole run:

ERR_PNPM_UNUSED_PATCH
The following patches were not used: next@16.3.5
Error: Upgrades were written, but the install did not finish, so the lockfile is out of date.

A patch keyed next@16.3.5 applies to that version only. --apply bumped the package anyway, the patch stopped matching, and pnpm refuses to install with an unused patch. Every other upgrade in the run was lost with it, and no PR was opened.

Fix

--apply now leaves such a package alone and upgrades the rest.

  • The detector reads patchedDependencies (from pnpm-workspace.yaml and the pnpm field of the root package.json) and stamps the pinned version selectors on each package.
  • A package is held only when none of its pinned patches covers the target version. Name-only patches (next) and ranges that still cover the target (next@^16.0.0) hold nothing.
  • Installing with unused patches allowed was rejected: it would silently drop a fix someone wrote on purpose.

The hold is never silent:

  • a warning on stderr naming each package and its patch key
  • heldByPatch on the entry in the --json report (additive, no schema bump)
  • a Held by pnpm patch (not applied) table in the Action's PR body; the package is no longer marked as applied

Testing

  • Reproduced on a scratch pnpm project with a real pinned patch: the published release exits 2 with ERR_PNPM_UNUSED_PATCH; this branch exits 0, upgrades the other package, and reports the held one.
  • pnpm test:coverage: 1930 tests pass, 100% coverage. Biome and tsc clean.

Notes

  • The Action runs inup@latest from npm, so users get this with the next release.
  • The picker is handled in a follow-up PR stacked on this one.

donfear and others added 2 commits October 10, 2026 17:01
A pnpm patch keyed to an exact version (`patchedDependencies: next@16.3.5`)
stops matching once the package is bumped, and pnpm refuses to install with
an unused patch (ERR_PNPM_UNUSED_PATCH). `--apply` wrote the bump anyway, so
the install failed and took every other upgrade in the run with it.

The detector now reads the pinned patches of each project and `--apply`
skips a package whose target version none of its patches cover. The hold is
reported rather than silent: a warning on stderr, `heldByPatch` on the
`--json` entry, and a "Held by pnpm patch" table in the Action's PR body.
Name-only patches and ranges that still cover the target hold nothing.
)

Selecting a package whose pnpm patch is pinned to the installed version
fails the install after the manifests are already written. The picker now
shows a `[PATCH]` badge on such a row, names the patch in the info modal,
and leaves it out of the `m` / `l` bulk selections. It can still be picked
by hand. The check is per option, so a range patch that covers the in-range
bump only blocks the major.
@donfear
donfear merged commit eb7816b into main Oct 10, 2026
33 checks passed
@donfear
donfear deleted the fix/pnpm-pinned-patch-hold branch October 10, 2026 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant