@@ -238,4 +238,53 @@ setTimeout(() => {}, 30_000);
238238 expect ( stderr ) . toMatch ( / E P I P E | w r i t e / i) ;
239239 expect ( stderr ) . not . toContain ( "Unhandled 'error' event" ) ;
240240 } ) ;
241+
242+ it ( "reports target stdout stream failures without an unhandled stream error" , async ( ) => {
243+ const spawnMockPath = await makeTempScript (
244+ "mock-target-stdout-error.cjs" ,
245+ String . raw `const childProcess = require("node:child_process");
246+ const { EventEmitter } = require("node:events");
247+ const { syncBuiltinESMExports } = require("node:module");
248+ const { PassThrough } = require("node:stream");
249+
250+ childProcess.spawn = () => {
251+ const child = new EventEmitter();
252+ child.stdin = new PassThrough();
253+ child.stdout = new PassThrough();
254+ child.kill = () => {};
255+
256+ process.nextTick(() => {
257+ child.stdout.emit("error", new Error("target stdout failed"));
258+ });
259+
260+ return child;
261+ };
262+ syncBuiltinESMExports();
263+ ` ,
264+ ) ;
265+
266+ const payload = encodePayload ( {
267+ targetCommand : `${ process . execPath } unused-target.cjs` ,
268+ mcpServers : [ ] ,
269+ } ) ;
270+
271+ const child = spawn ( process . execPath , [ "--require" , spawnMockPath , proxyPath , "--payload" , payload ] , {
272+ stdio : [ "pipe" , "pipe" , "pipe" ] ,
273+ cwd : process . cwd ( ) ,
274+ } ) ;
275+
276+ let stderr = "" ;
277+ child . stderr . on ( "data" , ( chunk ) => {
278+ stderr += String ( chunk ) ;
279+ } ) ;
280+ child . stdin . end ( ) ;
281+
282+ const exitCode = await new Promise < number | null > ( ( resolve ) => {
283+ child . once ( "close" , ( code ) => resolve ( code ) ) ;
284+ } ) ;
285+
286+ expect ( exitCode ) . toBe ( 1 ) ;
287+ expect ( stderr ) . toContain ( "target stdout failed" ) ;
288+ expect ( stderr ) . not . toContain ( "Unhandled 'error' event" ) ;
289+ } ) ;
241290} ) ;
0 commit comments