Skip to content

fix: fall back to older versions when pnpm trust downgrade blocks latest#14213

Merged
thavaahariharangit merged 8 commits intomainfrom
harry/pnpm-trust-downgrade-version-fallback
Feb 19, 2026
Merged

fix: fall back to older versions when pnpm trust downgrade blocks latest#14213
thavaahariharangit merged 8 commits intomainfrom
harry/pnpm-trust-downgrade-version-fallback

Conversation

@thavaahariharangit
Copy link
Contributor

@thavaahariharangit thavaahariharangit commented Feb 18, 2026

What are you trying to accomplish?

When pnpm blocks a version due to ERR_PNPM_TRUST_DOWNGRADE (provenance attestation disappeared), Dependabot previously skipped the update entirely. Now it iterates through older versions in descending order and selects the highest one that passes pnpm's trust check.

Problem:

  • The project currently uses chokidar@4.0.0.
  • The newest release, 4.0.3, fails the pnpm trust policy, so pnpm blocks installation.
  • 4.0.1 does comply with the trust policy and would be the expected fallback version.
  • However, Dependabot does not update to 4.0.1; instead, it skips the update entirely.

Anything you want to highlight for special attention from reviewers?

How will you know you've accomplished your goal?

After this changes Local dependabot cli run against the workflow ensures:

updater | 2026/02/18 16:11:58 INFO Results:
updater | +--------------------------------------------+
updater | |    Changes to Dependabot Pull Requests     |
updater | +---------+----------------------------------+
updater | | created | chokidar ( from 4.0.0 to 4.0.1 ) |
updater | +---------+----------------------------------+

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

Copilot AI review requested due to automatic review settings February 18, 2026 16:13
@thavaahariharangit thavaahariharangit requested a review from a team as a code owner February 18, 2026 16:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request enhances Dependabot's npm_and_yarn ecosystem to handle pnpm trust downgrade errors more gracefully. When pnpm detects ERR_PNPM_TRUST_DOWNGRADE (indicating a provenance attestation disappeared from a newer version), instead of skipping the update entirely, Dependabot now iterates through older versions in descending order to find the highest version that passes pnpm's trust check.

Changes:

  • Modified latest_resolvable_version method to call fallback logic when trust downgrade is detected instead of returning nil immediately
  • Added find_version_without_trust_downgrade method that iterates through candidate versions below the latest_allowable_version
  • Added version_has_trust_downgrade? method that checks if a specific version triggers the trust downgrade error
  • Enhanced test coverage with three scenarios: all versions fail, one older version passes, multiple older versions fail

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb Implements fallback logic to try older versions when pnpm trust downgrade is detected, including helper methods to iterate candidates and check individual versions
npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/version_resolver_spec.rb Adds comprehensive test coverage for trust downgrade scenarios with proper mocking of pnpm commands
Comments suppressed due to low confidence (1)

npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb:303

  • The method resets instance variables @trust_downgrade_detected and @peer_dependency_errors before each check. This is necessary because these are set as side effects by fetch_peer_dependency_errors. However, this means the final state of these variables after the method completes may not accurately reflect the state for the version that was ultimately selected. If other code depends on these instance variables after find_version_without_trust_downgrade is called, it may see stale or incorrect values. Consider documenting this behavior or refactoring to avoid side-effect-based state management.
        def version_has_trust_downgrade?(version)
          @trust_downgrade_detected = false
          @peer_dependency_errors = nil

          fetch_peer_dependency_errors(version: version)

@kbukum1
Copy link
Contributor

kbukum1 commented Feb 18, 2026

@thavaahariharangit ,

Can you go over the following AI suggestions?

Issue 1: Performance Concern with Unbounded Version Iteration

Location: find_version_without_trust_downgrade method in version_resolver.rb

Problem: The current implementation iterates through all candidate versions without a limit. Each iteration calls fetch_peer_dependency_errors, which spawns a pnpm subprocess. For packages with many published versions (e.g., lodash has 100+ versions), this could result in:

  • Excessive subprocess spawning
  • Significant latency during version resolution
  • Potential timeout issues in CI/CD environments

Suggestion: Consider adding a maximum iteration limit (e.g., 5-10 versions) to cap the number of trust checks performed. If no trusted version is found within the limit, return nil and log accordingly.


Issue 2: Side Effect Reliance and Type Safety

Location: version_has_trust_downgrade? method in version_resolver.rb

Problem: The method relies on fetch_peer_dependency_errors setting @trust_downgrade_detected as a side effect, then reads it back using T.unsafe() to bypass Sorbet type checking. This pattern has several concerns:

  • Fragility: If fetch_peer_dependency_errors implementation changes, this method could silently break
  • Readability: Side-effect based communication makes the code harder to reason about
  • Type Safety: Using T.unsafe defeats the purpose of Sorbet's type checking
  • State Pollution: The method mutates instance variables (@trust_downgrade_detected, @peer_dependency_errors) which could affect other code paths if not properly restored

Suggestion: Consider either:

  • Refactoring to restore the original instance variable state after the check
  • Modifying fetch_peer_dependency_errors to return the trust downgrade status directly rather than setting it as an instance variable

Issue 3: Missing Test Coverage for Edge Cases

Location: version_resolver_spec.rb

Problem: The current tests cover the happy paths well, but some edge cases are not covered:

Missing Scenario Why It Matters
Current version equals best candidate Could result in no-op PRs that update a package to the same version
Pre-release versions in candidate list Need to verify pre-releases are handled consistently with Dependabot's existing behavior
Unexpected errors during trust check Network failures or pnpm crashes could cause unhandled exceptions
Maximum iteration boundary If a limit is added, need to verify behavior when limit is reached

Suggestion: Add test cases covering:

  1. Scenario where the only passing version equals the current version
  2. Candidate list containing pre-release/beta versions
  3. Error handling when run_pnpm_command throws unexpected errors (not just HelperSubprocessFailed)
  4. Boundary behavior if/when a version check limit is implemented

Issue 4: User-Facing Documentation Gap

Location: PR description and user documentation

Problem: When this feature activates, users will receive PRs that update to a version that is not the latest. This could cause confusion because:

  • Users expect Dependabot to update to the latest version
  • The PR won't explain why an older version was selected
  • Users might think Dependabot is malfunctioning or misconfigured

Suggestion: Consider:

  1. Adding a note in the generated PR body explaining that the latest version was skipped due to pnpm trust policy (ERR_PNPM_TRUST_DOWNGRADE) and why
  2. Updating Dependabot's user-facing documentation to describe this fallback behavior
  3. Ensuring log messages are descriptive enough for users reviewing job logs to understand what happened

Summary Table

# Issue Severity Type
1 Unbounded version iteration Medium Performance
2 Side effect reliance with T.unsafe Low Code Quality
3 Missing edge case test coverage Medium Testing
4 No user-facing explanation Low Documentation

When pnpm blocks a version due to ERR_PNPM_TRUST_DOWNGRADE (provenance
attestation disappeared), Dependabot previously skipped the update
entirely. Now it iterates through older versions in descending order
and selects the highest one that passes pnpm's trust check.
@kbukum1 kbukum1 force-pushed the harry/pnpm-trust-downgrade-version-fallback branch from 022cf50 to 88f4dff Compare February 18, 2026 22:24
@thavaahariharangit thavaahariharangit merged commit ff015cb into main Feb 19, 2026
95 checks passed
@thavaahariharangit thavaahariharangit deleted the harry/pnpm-trust-downgrade-version-fallback branch February 19, 2026 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments