fix(headless): exit cleanly on stdout EPIPE (#804)

This commit is contained in:
paulbettner
2026-02-03 19:11:36 -06:00
committed by GitHub
parent d175b0e155
commit 7ee2b2ae90

View File

@@ -134,7 +134,6 @@ export async function handleHeadlessCommand(
const { toolFilter } = await import("./tools/filter");
toolFilter.setEnabledTools(values.tools as string);
}
// Set permission mode if provided (or via --yolo alias)
const permissionModeValue = values["permission-mode"] as string | undefined;
const yoloMode = values.yolo as boolean | undefined;
@@ -176,6 +175,25 @@ export async function handleHeadlessCommand(
const inputFormat = values["input-format"] as string | undefined;
const isBidirectionalMode = inputFormat === "stream-json";
// If headless output is being piped and the downstream closes early (e.g.
// `| head`), Node will throw EPIPE on stdout writes. Treat this as a normal
// termination rather than crashing with a stack trace.
//
// Note: this must be registered before any `console.log` in headless mode.
process.stdout.on("error", (err: unknown) => {
const code =
typeof err === "object" && err !== null && "code" in err
? (err as { code?: unknown }).code
: undefined;
if (code === "EPIPE") {
process.exit(0);
}
// Re-throw unknown stdout errors so they surface during tests/debugging.
throw err;
});
// Get prompt from either positional args or stdin (unless in bidirectional mode)
let prompt = positionals.slice(2).join(" ");