{"version":"2.1.281","anchor":"sdk-message-loop-pre-warmed-spare-sessions-park-and-refus","canonical_anchor":"sdk-message-loop-pre-warmed-spare-sessions-park-and-refus","heading":"Pre-warmed spare sessions stay idle and skip SessionEnd hooks","tier":"internal","area":"SDK","url":"https:\/\/changelogs.core-directive.com\/v\/2.1.281\/e\/sdk-message-loop-pre-warmed-spare-sessions-park-and-refus","release_url":"https:\/\/changelogs.core-directive.com\/v\/2.1.281","markdown":"### Pre-warmed spare sessions stay idle and skip SessionEnd hooks\n\nPre-started spare Claude Code processes now refuse most control requests while waiting and no longer run SessionEnd hooks\n\n**Unclear.** The finding does not say how spare sessions are started or claimed, or which control requests are allowed.\n\n**What**\n\nClaude Code can start a spare process in the background ahead of time, ready to become a session when one is needed. While a spare is `parked` (waiting), `claiming` (being taken for a session) or `failed`, it now behaves differently:\n\n- A parked spare records `spare_parked` before it reads any input.\n\n- Control requests, the instructions a program sends to a running Claude Code, are refused with an error unless they are of a permitted kind.\n\n- After start-up, a parked spare skips the step that sets up the terminal host, and it tracks idle time for when input arrives.\n\n- When the process shuts down, it does not run your `SessionEnd` hooks. Before, these hooks always ran at this point. A hook is a script you configure to run at set points, and `SessionEnd` runs when a session ends.\n\n**Why**\n\nA spare that never became a real session no longer runs your `SessionEnd` hooks, so those scripts do not fire for sessions you never opened. Refusing most requests while it waits keeps a spare idle until it is actually claimed.\n\n- Area: SDK\n- Tier: Under the hood\n- Useful: 1\/5\n- Signal: 2\/5"}