From 1a4160b3de700cab53df876b8bb47b3624b01073 Mon Sep 17 00:00:00 2001 From: Story Crater Bot <19826264+Riotpiaole@users.noreply.github.com> Date: Tue, 18 Aug 2026 19:13:07 -0700 Subject: [PATCH] fix(agent-pod): use process.exitCode not process.exit() in coordinator.js process.exit() right after console.log() can drop buffered stdout when it's piped (not a TTY) -- exactly kubectl exec's case. Explains the silent empty-output-exit-1 failures. process.exitCode + natural exit lets the event loop drain and flush first. --- k8s/apps/agent-pod/coordinator-configmap.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/k8s/apps/agent-pod/coordinator-configmap.yaml b/k8s/apps/agent-pod/coordinator-configmap.yaml index 6634187..2e99b6a 100644 --- a/k8s/apps/agent-pod/coordinator-configmap.yaml +++ b/k8s/apps/agent-pod/coordinator-configmap.yaml @@ -810,12 +810,18 @@ data: "usage: coordinator.js --repo [--tasks T0.1,T0.2;T1.1,T1.2,...] [--base main] [--branch ]\n" + " --tasks omitted: discovers phases from the cloned repo's own tasks/INDEX.md" ); - process.exit(1); + // process.exitCode + natural exit, not process.exit() -- stdout piped + // through kubectl exec (not a TTY) can drop buffered console.log/ + // console.error output if the process exits before it flushes. Setting + // exitCode and letting the event loop drain naturally is the + // documented-safe way to exit with a specific code without racing it. + process.exitCode = 1; + return; } const phases = opts.tasks ? opts.tasks.split(";").map((phase) => phase.split(",")) : null; const pipelineId = require("node:crypto").randomUUID(); const result = await runPipeline({ pipelineId, repo: opts.repo, baseBranch: opts.base, tasks: phases, branchName: opts.branch }); - process.exit(result.status === "completed" ? 0 : 1); + process.exitCode = result.status === "completed" ? 0 : 1; } if (require.main === module) {