Skip to content

check:i18n-walk-parity exits 1 for PREREQUISITE NOT MET — the code a real finding uses #16558

Description

@huangyiirene

Filed out-of-scope from work on #16147 (the resolver's region-level page:header route). Not touched there; filed unassigned.

The defect

scripts/check-i18n-walk-parity.mjs refuses correctly when its inputs are not built, prints the right words, and then returns the wrong number:

/** A hard prerequisite failure: says what it did NOT measure, and exits. */
function reportPrerequisiteNotMet(headline, lines) {
  console.error(`  check:i18n-walk-parity — PREREQUISITE NOT MET: ${headline}\n`);
  ...
  process.exit(1);
}

Exit 1 is the finding code. This repo already has one answer to that, with a name and a self-test: EXIT_PREREQUISITE_NOT_MET === 3 in scripts/import-prerequisite.mjs, whose own header states the reason in as many words:

Exit 1 from an unmet prerequisite and exit 1 from a real finding are the same reading — which is why the guarded refusal below does NOT keep that number.

Its siblings import it. Two of them are in this very family: check-i18n-bundles.mjs and check-i18n-coverage.mjs, plus check-dts-closure.mjs and check-doc-frontmatter.mjs. check-i18n-walk-parity.mjs is the one that spells the same headline by hand and keeps exit 1.

Measured, on a fresh per-task worktree

A gate sweep over the derived family list on a worktree where the dependency closure was built but packages/cli itself was not, exit codes captured before any pipe:

50 exit=3   pnpm check:dual-build-cjs-loads      <- PREREQUISITE NOT MET, reads as NOT MEASURED
52 exit=1   pnpm check:i18n-walk-parity          <- PREREQUISITE NOT MET, reads as a FINDING
67 exit=3   pnpm check:type-check-debt           <- PREREQUISITE NOT MET, reads as NOT MEASURED

All three refused for the same reason. Two are legible as NOT MEASURED from the number alone; the middle one is not. Its stderr does say so — but the number is what a sweep, a runner script, or a CI step condition reads, and it is the reading a seat writes into a report. The failure direction is a false RED reported against whatever landed most recently, which is exactly the near-miss import-prerequisite.mjs records as its reason for existing.

Repro

git worktree add --no-track ../objectstack-probe -b probe origin/main
cd ../objectstack-probe && pnpm install          # closure NOT built
pnpm check:i18n-walk-parity > /tmp/out.log 2>&1; echo "EXIT=$?"
# EXIT=1, with "PREREQUISITE NOT MET: the workspace CLI is not built" in the log

Suggested direction, for whoever takes it

Route the refusal through the shared helper rather than re-spelling it: import EXIT_PREREQUISITE_NOT_MET (and EXIT_FINDINGS) from scripts/import-prerequisite.mjs and return that code, the way check-dts-closure.mjs does — which also gets the shared "capture the code BEFORE any pipe" frame in the output for free. A self-test case asserting the refusal's code is 3 and is not the findings code would pin it; check-doc-frontmatter.mjs already carries a case in that exact shape.

Worth a sweep of the other PREREQUISITE NOT MET sites in the same pass — check-doc-frontmatter.mjs also has a hand-written exit(1) near its refusal text, unverified here as to whether it is on the refusal path or a different branch. That is a reading this card does not make.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions