From 69a310cc3f0bbba71e3a945c10af70146fab8ce9 Mon Sep 17 00:00:00 2001 From: Ramazan Rakhmatullin <32195167+grumpygordon@users.noreply.github.com> Date: Fri, 5 Dec 2025 01:28:36 +0300 Subject: [PATCH] fix: propagate CLI errors to pending control requests (#388) ## Summary When the CLI exits with an error (e.g., invalid session ID passed to `--resume`), signal all pending control requests immediately instead of waiting for the 60-second timeout. **The fix adds 4 lines** to the exception handler in `_read_messages`: ```python # Signal all pending control requests so they fail fast instead of timing out for request_id, event in list(self.pending_control_responses.items()): if request_id not in self.pending_control_results: self.pending_control_results[request_id] = e event.set() ``` ## Problem When the CLI exits with an error, the SDK's message reader catches it but doesn't notify pending control requests. This causes `initialize()` to wait for the full 60-second timeout even though the error is known within seconds. Example scenario: 1. User passes invalid session ID via `ClaudeAgentOptions(resume="invalid-id")` 2. CLI prints `No conversation found with session ID: xxx` and exits with code 1 3. SDK message reader catches the error after ~3 seconds 4. But `initialize()` keeps waiting for 60 seconds before timing out ## Solution The existing code at `_send_control_request` lines 361-362 already handles exceptions in results: ```python if isinstance(result, Exception): raise result ``` The fix simply signals all pending control events when an error occurs, allowing them to fail fast with the actual error instead of timing out. ## Test Plan - [ ] Test with invalid session ID - should fail fast (~3s) instead of timing out (60s) - [ ] Test normal flow still works - [ ] Test multiple pending requests all get signaled Fixes #387 --- src/claude_agent_sdk/_internal/query.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/claude_agent_sdk/_internal/query.py b/src/claude_agent_sdk/_internal/query.py index e48995f..8f0ac19 100644 --- a/src/claude_agent_sdk/_internal/query.py +++ b/src/claude_agent_sdk/_internal/query.py @@ -214,6 +214,11 @@ class Query: raise # Re-raise to properly handle cancellation except Exception as e: logger.error(f"Fatal error in message reader: {e}") + # Signal all pending control requests so they fail fast instead of timing out + for request_id, event in list(self.pending_control_responses.items()): + if request_id not in self.pending_control_results: + self.pending_control_results[request_id] = e + event.set() # Put error in stream so iterators can handle it await self._message_send.send({"type": "error", "error": str(e)}) finally: