{"record":{"id":"8b3fcd7e8f4f6d7a","repo":"pnpm/pnpm","slug":"pnpr-server-rejected-the-lockfile-under-the-verifi","errorCode":null,"errorMessage":"pnpr server rejected the lockfile under the verification policy:\n${rendered}","messagePattern":"pnpr server rejected the lockfile under the verification policy:\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pnpr/client/src/resolveViaPnprServer.ts","lineNumber":199,"sourceCode":"    preferFrozenLockfile: opts.preferFrozenLockfile,\n    // Sent as-is: `opts.lockfile` is already the on-disk format the wire\n    // protocol carries (split `packages`/`snapshots`, `{ specifier, version }`\n    // importer deps).\n    lockfile: opts.lockfile,\n  })\n\n  const body = await postResolve(opts.registryUrl, requestBody, opts.authorization)\n\n  const terminal = parseTerminalFrame(body.toString('utf-8'))\n\n  if (terminal.type === 'error') {\n    throw new Error(terminal.message)\n  }\n  if (terminal.type === 'violations') {\n    const rendered = terminal.violations\n      .map((violation) => `  ${violation.name}@${violation.version}: ${violation.reason}`)\n      .join('\\n')\n    throw new Error(`pnpr server rejected the lockfile under the verification policy:\\n${rendered}`)\n  }\n\n  return {\n    // The server speaks the on-disk lockfile format; convert it to the\n    // in-memory `LockfileObject` the rest of pnpm consumes.\n    lockfile: convertToLockfileObject(terminal.lockfile),\n    stats: terminal.stats,\n  }\n}\n\ntype TerminalFrame = Extract<ResolveFrame, { type: 'done' | 'error' | 'violations' }>\n\n/**\n * Parse the NDJSON `/-/pnpr/v0/resolve` body and return its single terminal\n * frame. `package` frames are skipped — this client fetches tarballs the\n * normal way after resolution rather than overlapping fetch with the\n * stream. Throws on an unknown frame type (so a protocol mismatch fails\n * fast here rather than as a confusing lockfile error downstream) or if","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpr/client/src/resolveViaPnprServer.ts#L181-L217","documentation":"A pnpr registry can enforce a verification policy over resolved packages (trust, provenance, organizational rules). When resolution succeeds but one or more packages violate the policy, the server returns a `violations` terminal frame listing `name@version` and a reason each; the client renders the list and throws. This is a deliberate policy rejection, not a network or resolver failure — proceeding requires changing the dependencies or the policy.","triggerScenarios":"Installing dependencies through a pnpr registry configured with a verification policy where at least one resolved package fails verification — untrusted tarball, missing attestation, banned version or license, unapproved scope.","commonSituations":"Corporate registries enforcing supply-chain rules; a transitive dependency bumps to a version that trips the policy; a newly enabled policy applied to an existing lockfile.","solutions":["Read the rendered list — each line names the exact package and the reason it was rejected","Bump, replace, or pnpm-overrides the offending packages so they satisfy the policy","If you operate the server, adjust the verification policy or grant an exception for the listed packages","Otherwise ask the package maintainers to publish a compliant version"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await resolveViaPnprServer(opts)\n} catch (err) {\n  if (err instanceof Error && err.message.includes('rejected the lockfile under the verification policy')) {\n    const violations = parseViolationLines(err.message) // name@version: reason\n    failFast(`policy violations (${violations.length}):\\n${violations.join('\\n')}`)\n  }\n  throw err\n}","preventionTips":["Treat the violation list as actionable input: each line names the package and reason","Pre-check new/updated dependencies against the server policy before committing the manifest","Coordinate policy changes with lockfile owners — a new policy can reject an existing lockfile"],"tags":["pnpm","pnpr","policy","supply-chain","verification","lockfile"],"backgroundTag":"dependency-policy-violation","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}