From 8920d773de13d0995a7c8142fdcdaf1458c9d4c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=9D=B0?= Date: Thu, 9 Apr 2026 10:01:45 +0800 Subject: [PATCH] fix: handle EAGAIN error when reading stdin in hook scripts When Claude Code runs hook scripts, stdin (fd 0) may be set to non-blocking mode (O_NONBLOCK). If no data is available, `fs.readFileSync(0, "utf8")` throws EAGAIN ("resource temporarily unavailable"), causing the hook to crash instead of gracefully handling the empty input. This wraps the readFileSync(0) calls in readHookInput() with a try-catch that treats EAGAIN/EWOULDBLOCK the same as empty input (returns {}), matching the existing behavior for empty stdin. Affected scripts: - stop-review-gate-hook.mjs - session-lifecycle-hook.mjs Co-Authored-By: Claude Opus 4.6 (1M context) --- plugins/codex/scripts/session-lifecycle-hook.mjs | 10 +++++++++- plugins/codex/scripts/stop-review-gate-hook.mjs | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/codex/scripts/session-lifecycle-hook.mjs b/plugins/codex/scripts/session-lifecycle-hook.mjs index 9655eae..1694c0c 100644 --- a/plugins/codex/scripts/session-lifecycle-hook.mjs +++ b/plugins/codex/scripts/session-lifecycle-hook.mjs @@ -20,7 +20,15 @@ export const SESSION_ID_ENV = "CODEX_COMPANION_SESSION_ID"; const PLUGIN_DATA_ENV = "CLAUDE_PLUGIN_DATA"; function readHookInput() { - const raw = fs.readFileSync(0, "utf8").trim(); + let raw; + try { + raw = fs.readFileSync(0, "utf8").trim(); + } catch (err) { + if (err.code === "EAGAIN" || err.code === "EWOULDBLOCK") { + return {}; + } + throw err; + } if (!raw) { return {}; } diff --git a/plugins/codex/scripts/stop-review-gate-hook.mjs b/plugins/codex/scripts/stop-review-gate-hook.mjs index 2346bdc..c56b340 100644 --- a/plugins/codex/scripts/stop-review-gate-hook.mjs +++ b/plugins/codex/scripts/stop-review-gate-hook.mjs @@ -19,7 +19,15 @@ const ROOT_DIR = path.resolve(SCRIPT_DIR, ".."); const STOP_REVIEW_TASK_MARKER = "Run a stop-gate review of the previous Claude turn."; function readHookInput() { - const raw = fs.readFileSync(0, "utf8").trim(); + let raw; + try { + raw = fs.readFileSync(0, "utf8").trim(); + } catch (err) { + if (err.code === "EAGAIN" || err.code === "EWOULDBLOCK") { + return {}; + } + throw err; + } if (!raw) { return {}; }