DEV Community

Scarab Systems
Scarab Systems

Posted on

Scarab Field Test #021 — pnpm Self-Upgrade No-Manifest Boundary

Target: pnpm/pnpm
Issue: pnpm/pnpm#12240
PR: pnpm/pnpm#12301
Public branch: https://github.com/scarab-systems/pnpm/tree/fix/deps-status-no-manifest
Latest pushed commit: cb68ac1af0dcffbe4fb607a10b0df2046d2490ba

This field test targeted a pnpm command-routing failure where pnpm self-upgrade could fail outside a project directory with:
ERR_PNPM_NO_PKG_MANIFEST

The issue looked simple at the surface: a global/self command should not require a project manifest just because the current working directory is not inside a package.

But the repair boundary was more specific than “ignore missing manifest.”

The problem was in the dependency-status verification path.

When dependency status was unavailable because there was no project manifest, the command could fall through into the auto-install path. That made a self-upgrade/global-style command behave as if it needed a local project manifest.

Failure shape

The failing behavior was:
pnpm self-upgrade
run outside a project directory
dependency status cannot be established from a project manifest
the command path falls into install/manifest expectations
result: ERR_PNPM_NO_PKG_MANIFEST

That is the wrong ownership boundary.

A self-upgrade command should not inherit project-manifest preconditions when there is no local project context.

Boundary

The boundary here is:
global/self command execution
versus
project dependency-status verification

Dependency-status verification can be useful when a command is operating inside a project.

But when there is no project manifest and the command is not recursive/all-projects, “dependency status unavailable” should not automatically mean “try to auto-install project dependencies.”

There are two different cases:

  1. Dependency status is unavailable because there is no project manifest.
  2. Dependency status is unexpectedly unavailable even though a root project manifest exists.

Those cases should not behave the same.

The repair preserves that distinction.

What changed

The patch updates:
exec/commands/src/runDepsStatusCheck.ts

The previous guard was a single truthy check:
if (upToDate) return

The updated logic handles the relevant cases explicitly:
if (upToDate === true) return
if (upToDate === undefined && opts.allProjects == null && opts.rootProjectManifest == null) return

That second condition is the important one.

It exits early only for the no-manifest, non-recursive case.

It does not turn every undefined dependency-status result into “skip install.”

If a root project manifest exists and dependency status unexpectedly comes back unavailable, the auto-install behavior is still preserved.

Why the first version changed

The first PR shape used a broader guard.

Review automation correctly flagged that because upToDate !== false was too wide.

That version would have treated too many unavailable dependency-status cases as safe to skip.

The patch was tightened so only the intended no-manifest path exits early.

That made the repair more precise:
no project manifest
not all-projects / recursive
dependency status unavailable
do not fall into auto-install

But if a project manifest exists and dependency status is unexpectedly unavailable, keep the existing install path.

That is the difference between fixing the reported failure and weakening the command contract.

Test coverage

Regression coverage was added for both sides of the boundary.

The tests prove:
no auto-install when dependency status is unavailable because there is no project manifest
auto-install still runs when dependency status is unexpectedly unavailable but a root project manifest exists

That second test matters.

It prevents the fix from becoming too broad.

The patch is not saying “undefined means safe.”

It is saying “undefined with no project manifest in this command context should not trigger project install behavior.”

Changeset

A patch changeset was added for:
@pnpm/exec.commands
pnpm

Validation

The updated patch passed:
pnpm run lint in exec/commands
focused Jest for test/runDepsStatusCheck.test.ts
focused Jest for test/createInstallArgs.test.ts
2 suites / 8 tests passed
tsgo --build --pretty false
git diff --check
pnpm pre-push hook completed and pushed

Only unrelated existing skipped-test warnings appeared.

Review state

The first review round improved the patch.

The broader guard was corrected.

The current repair is narrower and preserves the existing fallback behavior for unexpected dependency-status results when a project manifest exists.

CodeRabbit reported no actionable comments after the update.

The PR remains open upstream.

Field test result

This was a good example of a field test where the first repair direction was close, but not precise enough.

The issue was not simply:
self-upgrade should ignore missing manifests

The better repair boundary was:
dependency-status verification should not fall into project auto-install when there is no project manifest and no all-projects context

That keeps the global/self command path separate from project dependency repair behavior.

The final patch is small, but the boundary matters.

A package manager command should not accidentally inherit a project-local precondition when it is being run outside a project.

The repair keeps that contract intact.

What this field test showed

This field test did not produce a magical one-line answer from the first diagnostic pass.

The broader diagnostic run surfaced dependency/runtime/verification pressure around the issue. The final bounded repair was localized using the issue context, the surfaced repair territory, and review feedback.

That is still a strong result.

It shows the diagnostic process can help narrow the correct repair surface, but it also shows where the process still needs better ranking from broad findings to exact repair candidate.

That is useful signal.

A good field test does not only prove the patch.

It also shows where the diagnostic workflow needs to get sharper.

Public claim

The correct claim for this field test is:

SDS/Scarab helped drive a bounded repair for pnpm self-upgrade failing outside a project directory by separating no-manifest dependency-status unavailability from unexpected dependency-status failure inside a project.

The patch prevents the no-manifest self-upgrade path from falling into auto-install/project-manifest behavior while preserving the existing fallback when a root project manifest exists.

That is the repair.

Disclosure: This field report was prepared with AI-assisted editing from my own field-test notes, PR records, validation output, and repair summary. The technical claims, patch behavior, and final wording were reviewed before publication.

Top comments (0)