github/copilot-sdk · error · TimeoutError
Timeout after s waiting for session.idle
Error message
Timeout after {timeout}s waiting for session.idle What it means
Raised by CopilotSession.send_and_wait in python/copilot/session.py when the session does not emit a session.idle event within the given timeout after a prompt is sent. asyncio.wait_for raises TimeoutError, which is caught, logged, and re-raised with a message including the timeout in seconds.
Solutions
- Increase the timeout argument passed to send_and_wait to exceed the expected turn duration.
- Prefer listening for the final assistant message / session.idle via session.on() with your own timeout policy instead of a tight send_and_wait timeout.
- Check for a preceding SessionError event — a hung or failed turn may never emit idle; inspect session logs.
- If using AUTOPILOT mode, don't rely on idle-based waiting; consume assistant message events directly.
- Retry the send if the turn is idempotent, or resume the session and continue.
Example fix
// before message = await session.send_and_wait(prompt, timeout=30) # too short for long turns // after message = await session.send_and_wait(prompt, timeout=600) # allow long agent turns
Defensive patterns
Strategy: retry
Validate before calling
expected_turn_seconds = estimate_turn_duration(prompt)
if expected_turn_seconds >= timeout:
timeout = expected_turn_seconds * 2 Type guard
null
Try / catch
try:
message = await session.send_and_wait(prompt, timeout=timeout)
except TimeoutError:
logging.warning("turn exceeded %ss; continuing to stream events", timeout)
message = await wait_for_next_assistant_message(session, extra_timeout=timeout) Prevention
- Set timeouts relative to expected agent workload, not fixed small defaults.
- Subscribe via session.on() so you keep receiving events even after a send_and_wait timeout.
- Watch for SessionError events — a broken turn may never emit idle.
- Avoid idle-based waiting in AUTOPILOT mode.
When it happens
Trigger: Calling send_and_wait(prompt, timeout=N) where the agent turn takes longer than N seconds, or the session.idle event never fires (e.g. idle arrives in AUTOPILOT mode which the handler deliberately ignores, or the session errored/hung).
Common situations: Long-running agent tasks (big refactors, slow tools) exceeding a default or hard-coded timeout; extremely slow network to the Copilot backend; a mode where idle events are suppressed (SessionMode.AUTOPILOT); a stuck tool call that never completes.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- waiting for session.idle
- CopilotClient is in Mode = CopilotClientMode.Empty but the…
- CopilotClient is in Mode = EMPTY but the session config did…
- Factory limit "timeoutSeconds" must not exceed
- failed to abort session
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/3b3238457bd993d9.
Report an issue: GitHub.
Appendix: source
Thrown at python/copilot/session.py:1930
logger,
logging.DEBUG,
"CopilotSession.send_and_wait complete",
total_start,
session_id=self.session_id,
completed_by="idle",
assistant_message_received=last_assistant_message is not None,
)
return last_assistant_message
except TimeoutError:
log_timing(
logger,
logging.WARNING,
"CopilotSession.send_and_wait failed",
total_start,
session_id=self.session_id,
completed_by="timeout",
)
raise TimeoutError(f"Timeout after {timeout}s waiting for session.idle")
finally:
unsubscribe()
def on(self, handler: Callable[[SessionEvent], None]) -> Callable[[], None]:
"""
Subscribe to events from this session.
Events include assistant messages, tool executions, errors, and session
state changes. Multiple handlers can be registered and will all receive
events.
Args:
handler: A callback function that receives session events. The function
takes a single :class:`SessionEvent` argument and returns None.
Returns:
A function that, when called, unsubscribes the handler.
View on GitHub (pinned to cd8cf15dc3)