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

  1. Increase the timeout argument passed to send_and_wait to exceed the expected turn duration.
  2. 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.
  3. Check for a preceding SessionError event — a hung or failed turn may never emit idle; inspect session logs.
  4. If using AUTOPILOT mode, don't rely on idle-based waiting; consume assistant message events directly.
  5. 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

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.

Related errors


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)