From b9ab4d8306abd1bec53416968340d2a9b6df7e02 Mon Sep 17 00:00:00 2001 From: levontumanyan <5532305+levontumanyan@users.noreply.github.com> Date: Sat, 20 Jun 2026 21:49:58 +0200 Subject: [PATCH 1/2] fix(factory): route JSON validation error through commander writeErr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test for JSON-format input validation errors was failing on Node.js 22 after the commander v14 → v15 upgrade (#410). Commander 15 is ESM-only, and when loaded via dynamic import() from a CommonJS context (tsx-compiled tests), patching process.stderr.write globally becomes unreliable on Node.js 22 due to CJS/ESM boundary handling. The second test in the suite was consistently getting null for its captured output. Fix: use cmd.configureOutput().writeErr() instead of process.stderr.write() directly, which routes through commander's own output configuration layer — the same channel the test already captures via cmd.configureOutput({ writeErr }). Co-Authored-By: Claude Sonnet 4.6 --- src/factory.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/factory.ts b/src/factory.ts index 04ce03b3..b1726d48 100644 --- a/src/factory.ts +++ b/src/factory.ts @@ -571,7 +571,8 @@ export function defineCommand (config: CommandConfig): O const { simplifyZodIssues, formatIssuesText } = await import('./lib/zod-error.js') const issues = simplifyZodIssues(result.error.issues) if (jsonFormat === true) { - process.stderr.write(JSON.stringify({ + const writeErr = cmd.configureOutput().writeErr ?? ((s: string) => process.stderr.write(s)) + writeErr(JSON.stringify({ error: { code: 'input_validation_failed', message: `Input validation failed with ${issues.length} issue(s)`, From 7f9bd2d6e55d2230b69fb60cffef9414eef809ad Mon Sep 17 00:00:00 2001 From: levontumanyan <5532305+levontumanyan@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:24:43 +0200 Subject: [PATCH 2/2] fix(factory): route JSON validation error through commander writeErr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test for JSON-format input validation errors was failing on Node.js 22 (Linux) after the commander v14 → v15 upgrade (#410). Commander 15 is ESM-only, and on Linux Node 22.22.x the combination of global process.stderr.write patching in the test helper with tsx/esm caused the captured output to be unreliable — specifically the second test in the suite got an empty or non-JSON buffer, making parsed come back null. Two-part fix: 1. factory.ts: route the JSON error through cmd.configureOutput().writeErr() instead of process.stderr.write() directly, respecting commander's own output configuration layer. 2. test: remove global process.stdout/stderr.write patching from invokeWithJsonFormat and rely solely on configureOutput — which is already set up to capture output. This eliminates the global-state mutation that was the root cause of the Linux-specific failure. Co-Authored-By: Claude Sonnet 4.6 --- test/factory.test.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/factory.test.ts b/test/factory.test.ts index e7100144..6e433355 100644 --- a/test/factory.test.ts +++ b/test/factory.test.ts @@ -1705,19 +1705,12 @@ describe('defineCommand', () => { prog.exitOverride() cmd.exitOverride() let out = '' - const origOut = process.stdout.write.bind(process.stdout) - const origErr = process.stderr.write.bind(process.stderr) - process.stdout.write = (chunk: unknown) => { out += String(chunk); return true } - process.stderr.write = (chunk: unknown) => { out += String(chunk); return true } prog.configureOutput({ writeOut: (s) => { out += s }, writeErr: (s) => { out += s } }) cmd.configureOutput({ writeOut: (s) => { out += s }, writeErr: (s) => { out += s } }) try { await prog.parseAsync(['--json', cmd.name(), ...argv], { from: 'user' }) } catch { // exitOverride throws on cmd.error(); that's expected - } finally { - process.stdout.write = origOut - process.stderr.write = origErr } let parsed: unknown = null try { parsed = JSON.parse(out) } catch { /* not JSON - test will fail on assertion */ }