Skip to content

Release v0.3.0 blocked: Node.js 22 test failure from commander v15 upgrade #455

Description

@levontumanyan

Summary

The release PR #395 (v0.3.0) is currently blocked because CI is failing on Node.js 22 (ubuntu-latest). This issue tracks the root cause, the current fix, and open questions about long-term correctness.

Background

PR #410 upgraded commander v14 → v15. Commander 15 is ESM-only, which introduced a subtle Linux-specific failure in the test suite on Node.js 22.22.x.

What's failing

In test/factory.test.ts, the invokeWithJsonFormat helper function patches process.stderr.write globally to capture output. On Linux Node 22.22.x (but not macOS, and not Node 24/25), something in the tsx/esm + Node internals writes to process.stderr.write between tests in the schema input - JSON format error output suite, contaminating the captured out buffer with non-JSON content. When JSON.parse(out) is called afterwards, it fails silently and parsed comes back null, causing:

TypeError: Cannot read properties of null (reading 'error')
  at factory.test.ts:1758

Only the second test in the suite fails consistently — the first test runs clean but leaves behind something that poisons the global stderr write handle for the next test.

Current fix — PR #444

Two-part change:

  1. src/factory.ts — the JSON-format input validation error was written directly to process.stderr.write(json). Changed to route through cmd.configureOutput().writeErr(json) instead, which respects commander's own output configuration layer (the same channel the test helper already captures via cmd.configureOutput({ writeErr })).

  2. test/factory.test.ts — removed the global process.stdout/stderr.write patching from invokeWithJsonFormat entirely. The helper now relies solely on configureOutput captures, which are per-invocation and don't touch global state.

The fix passes locally on Node 22.23.0 (macOS) and Node 26 across all 5 tests in the suite.

Uncertainty — is this the right long-term fix?

I am not fully confident this is the correct long-term approach. A few open questions:

1. Other direct stream writes in factory.ts

There are roughly 10 other process.stdout.write / process.stderr.write calls in factory.ts inside action handlers (lines ~516, 589, 591, 601, 603, 615, 619, 623, 631, 633, 635). PR #444 only fixes the one failing line (574). The others aren't currently failing — but they carry the same structural risk on Node.js 22. Should a follow-up PR migrate all of them to route through cmd.configureOutput()?

2. Root cause is still somewhat unclear

I cannot fully explain why Linux Node 22.22.3 behaves differently from macOS Node 22.23.0. Node 22.23.0 is a security-only release with no test runner changes. The failure may be an environment artifact specific to the ubuntu-latest runner image rather than a real Node.js version difference. If so, the test change (removing global patches) is the more important fix, and the factory change may be incidental.

3. process.stderr.write patching pattern elsewhere

Several other test helpers in factory.test.ts also patch process.stdout/stderr.write globally (lines ~1865, 2014, 3739, 3761). If the root cause is a platform-specific interaction with the tsx/esm loader, those helpers could exhibit similar issues in the future.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions