Skip to content

fix(cli): handle pnpm 10+ ERR_PNPM_TRUST_DOWNGRADE in docs preview#14965

Open
fern-support wants to merge 2 commits intomainfrom
devin/1776109736-fix-pnpm-trust-downgrade
Open

fix(cli): handle pnpm 10+ ERR_PNPM_TRUST_DOWNGRADE in docs preview#14965
fern-support wants to merge 2 commits intomainfrom
devin/1776109736-fix-pnpm-trust-downgrade

Conversation

@fern-support
Copy link
Copy Markdown
Collaborator

@fern-support fern-support commented Apr 13, 2026

Description

Fixes fern docs dev failing on Windows 11 with pnpm 10+ when trustPolicy: no-downgrade is configured. The error occurs because pnpm propagates supply-chain security settings as npm_config_* env vars to child processes, causing pnpm install in the standalone preview bundle to fail with ERR_PNPM_TRUST_DOWNGRADE for packages like undici-types@6.21.0 that have lost provenance attestation between versions.

Changes Made

  • Added getCleanPnpmEnv() helper that strips pnpm supply-chain security env vars (npm_config_trust_policy, npm_config_strict_dep_builds, npm_config_minimum_release_age, npm_config_block_exotic_subdeps) before running pnpm commands in the preview bundle folder
  • Applied clean env with extendEnv: false to all three pnpm calls in downloadLocalDocsBundle.ts (two pnpm i esbuild calls and one pnpm install)
  • Added specific ERR_PNPM_TRUST_DOWNGRADE error detection in the Windows pnpm install catch block — when detected, strips trustPolicy from the standalone pnpm-workspace.yaml and retries
  • Added unreleased changelog entry

Testing

  • Manual code review of all pnpm invocation paths
  • Verified lint passes (pnpm run check)
  • Unit tests — no existing tests for this module; the fix is in error handling paths that require Windows + pnpm 10+ to reproduce

Link to Devin session: https://app.devin.ai/sessions/1be76045381f46ec95ceb354512677b1
Requested by: @cdonel707


Open with Devin

Co-Authored-By: Chris McDonnell <chris@buildwithfern.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

);
if (pnpmWorkspaceExists) {
const content = (await readFile(pnpmWorkspacePath)).toString();
const updatedContent = content.replace(/^trustPolicy:.*$/gm, "");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Regex only strips the trustPolicy: header line, leaving orphaned indented YAML that invalidates the file

The regex /^trustPolicy:.*$/gm at line 450 only removes lines that start with trustPolicy:, but in pnpm 10+ the trustPolicy setting is typically a multi-line YAML block with nested indented content (e.g., dependencies:, package names, version constraints, attestation settings). After the replacement, the indented sub-keys remain as orphaned YAML content, producing an invalid pnpm-workspace.yaml that will cause the retry pnpm install to also fail — this time with a YAML parse error rather than the trust downgrade error, resulting in a confusing error message.

Example of incompletely stripped YAML

Before:

packages:
  - '.'
trustPolicy:
  dependencies:
    undici-types:
      - version: ">=6.21.0"
        attestation: npm

After the regex replace:

packages:
  - '.'

  dependencies:
    undici-types:
      - version: ">=6.21.0"
        attestation: npm

The orphaned indented lines make the YAML invalid or attach to the wrong key.

Suggested change
const updatedContent = content.replace(/^trustPolicy:.*$/gm, "");
const updatedContent = content.replace(/^trustPolicy:.*$(?:\n(?=[ \t]).*$)*/gm, "");
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — trustPolicy is a simple scalar in practice (trustPolicy: no-downgrade), but the more defensive regex is a reasonable safety measure. Applied the suggested regex to also strip any indented sub-keys: b204c22.

…keys

Co-Authored-By: Chris McDonnell <chris@buildwithfern.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants