github/copilot-sdk · warning · RuntimeError

Request cancelled by runtime

Error message

Request cancelled by runtime

What it means

_run_cancellable supervises the request task against a cancellation signal: when the cancellation waiter fires, it awaits (and discards) the task's unwind, then unconditionally raises this RuntimeError to abort the HTTP handling flow. It converts a runtime-initiated cancellation into an exception the caller can observe and report.

Solutions

  1. Treat this RuntimeError as an expected cancellation outcome: catch it around the request invocation and log/skip rather than retrying.
  2. Check cancellation state before starting expensive work inside the handler so work stops early.
  3. If it fires spuriously, verify the runtime's cancellation conditions (timeouts, client lifetime) in configuration.

Example fix

// before
await _run_cancellable(handler_task, cancel_waiter)

// after
try:
    await _run_cancellable(handler_task, cancel_waiter)
except RuntimeError as e:
    if "Request cancelled by runtime" in str(e):
        logger.info("request cancelled by runtime; aborting")
    else:
        raise
Defensive patterns

Strategy: try-catch

Try / catch

try:
    await _run_cancellable(task, cancel_waiter)
except RuntimeError as e:
    if str(e) == "Request cancelled by runtime":
        return  # expected cancellation path
    raise

Prevention

When it happens

Trigger: The runtime's cancellation signal fires while _handle_http is executing — the client aborted the request, the runtime timed it out, or the session was shut down — and the supervised task was cancelled via the waiter mechanism.

Common situations: Client disconnects mid-request; runtime-imposed request deadlines; shutdown of the Copilot extension while an HTTP exchange is in flight.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/034da230e2c72f94. Report an issue: GitHub.

Appendix: source

Thrown at python/copilot/copilot_request_handler.py:690

    """Run ``coro`` but abort it (and raise) when ``cancel_event`` fires."""
    task = asyncio.ensure_future(coro)
    waiter = asyncio.ensure_future(cancel_event.wait())
    try:
        done, _ = await asyncio.wait({task, waiter}, return_when=asyncio.FIRST_COMPLETED)
        if task in done:
            exc = task.exception()
            if exc is not None:
                raise exc
            return
        # Cancellation fired first.
        task.cancel()
        try:
            await task
        except (asyncio.CancelledError, Exception):
            # The awaited task was cancelled; its unwind exception is expected
            # and irrelevant — we raise the cancellation result below.
            pass
        raise RuntimeError("Request cancelled by runtime")
    finally:
        if not waiter.done():
            waiter.cancel()


async def _build_httpx_request(exchange: _CopilotRequestExchange) -> httpx.Request:
    import httpx

    header_pairs = [
        (name, value)
        for name, values in exchange.headers.items()
        if name.lower() not in _FORBIDDEN_REQUEST_HEADERS
        for value in (values or [])
    ]
    method = exchange.method.upper()
    has_body = method not in ("GET", "HEAD")
    body = await _drain_async(exchange.request_body)
    content = body if (has_body and body) else None

View on GitHub (pinned to cd8cf15dc3)