{"record":{"id":"6509876a5027c886","repo":"pnpm/pnpm","slug":"unused-patch","errorCode":"UNUSED_PATCH","errorMessage":"The following patches were not used: ${unusedPatches.join(', ')}","messagePattern":"The following patches were not used: (.+?)","errorType":"error_code","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/patching/config/src/verifyPatches.ts","lineNumber":29,"sourceCode":"}\n\nexport function verifyPatches ({\n  patchedDependencies,\n  appliedPatches,\n  allowUnusedPatches,\n}: VerifyPatchesOptions): void {\n  const unusedPatches: string[] = []\n  for (const patchKey of allPatchKeys(patchedDependencies)) {\n    if (!appliedPatches.has(patchKey)) unusedPatches.push(patchKey)\n  }\n\n  if (!unusedPatches.length) return\n  const message = `The following patches were not used: ${unusedPatches.join(', ')}`\n  if (allowUnusedPatches) {\n    globalWarn(message)\n    return\n  }\n  throw new PnpmError('UNUSED_PATCH', message, {\n    hint: 'Either remove them from \"patchedDependencies\" or update them to match packages in your dependencies.',\n  })\n}\n","sourceCodeStart":11,"sourceCodeEnd":33,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/patching/config/src/verifyPatches.ts#L11-L33","documentation":"After install, every configured patch key must have been applied to something in the resolved graph; leftovers throw UNUSED_PATCH. A patch goes unused when its key matches no installed package/version — the dependency was removed, the locked version drifted outside the key, or the name is typo'd. With `allowUnusedPatches: true` (pnpm settings in the root package.json) it downgrades to a warning.","triggerScenarios":"Removing or renaming the patched dependency while leaving the patchedDependencies entry; the installed version moves outside the key's exact version or range; a typo'd package name; a patch declared in a workspace root whose packages no longer use the dependency.","commonSituations":"Installs failing right after a dependency upgrade; dependency cleanup without patch cleanup; generated manifests retaining stale entries.","solutions":["Remove the stale entry: `pnpm patch-remove <key>`","Update the key to the version now installed (regenerate with `pnpm patch` if the diff no longer applies)","Opt out of the hard failure with `\"pnpm\": { \"allowUnusedPatches\": true }` in the root package.json — install then only warns"],"exampleFix":"// before\n\"pnpm\": { \"patchedDependencies\": { \"foo@1.2.3\": \"patches/foo.patch\" } } // foo@1.3.0 installs\n\n// after\n\"pnpm\": { \"patchedDependencies\": { \"foo@1.3.0\": \"patches/foo.patch\" } }","handlingStrategy":"validation","validationCode":"import { satisfies, valid } from 'semver'\nimport { readCurrentLockfile } from '@pnpm/lockfile.fs'\n\nconst lockfile = await readCurrentLockfile(path.join(modulesDir, '.pnpm'), { ignoreIncompatible: true })\nconst snapshots = Object.keys(lockfile?.packages ?? {})\nfor (const key of Object.keys(patchedDependencies)) {\n  const at = key.lastIndexOf('@')\n  const name = at > 0 ? key.slice(0, at) : key\n  const version = at > 0 ? key.slice(at + 1) : undefined\n  const matches = snapshots.some(depPath =>\n    depPath.includes(`/${name}/`) && (version == null || valid(version) != null\n      ? depPath.endsWith(`@${version}`)\n      : snapshots.some(() => true) && version === '*')\n  )\n  if (!matches) console.warn(`Patch key ${key} matches nothing in the lockfile`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await installCmd.handler(opts)\n} catch (err) {\n  if (isPnpmErrorCode(err, 'UNUSED_PATCH')) {\n    // message lists unused keys: remove them (pnpm patch-remove) or set pnpm.allowUnusedPatches=true in the root manifest\n  } else throw err\n}","preventionTips":["Remove patch entries in the same change that removes or upgrades the patched dependency","Set `pnpm.allowUnusedPatches: true` in the root package.json when stale entries are acceptable","After upgrades, compare patchedDependencies keys against installed versions before running install in CI"],"tags":["pnpm","patching","manifest","install"],"backgroundTag":"unused-patch","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}