github/copilot-sdk · warning · OperationCanceledException

Request cancelled by runtime

Error message

Request cancelled by runtime

What it means

During LLM inference response streaming, the exchange consumes a cancel/end channel. When a cancel item arrives, the pending response body is completed and an OperationCanceledException is thrown to abort the request, with an optional reason from the runtime.

Solutions

  1. Wrap response consumption in try/catch for OperationCanceledException and treat it as normal cancellation
  2. Check item.CancelReason (the exception message suffix) to identify why the runtime cancelled
  3. Implement retry with backoff for cancellable inference requests when appropriate
  4. Ensure long-running inference calls pass/observe cancellation tokens so client-side state stays consistent

Example fix

// before
await foreach (var chunk in exchange.ReadResponseAsync()) { Process(chunk); }
// after
try { await foreach (var chunk in exchange.ReadResponseAsync()) { Process(chunk); } }
catch (OperationCanceledException) { /* runtime cancelled the request; cleanup */ }
Defensive patterns

Strategy: try-catch

Try / catch

try { await foreach (var chunk in exchange.ReadResponseAsync()) { ... } }
catch (OperationCanceledException) { /* expected on runtime cancellation */ }

Prevention

When it happens

Trigger: The runtime cancels the in-flight LLM inference request while the client is reading response chunks — e.g. the originating RPC was aborted, a timeout fired, or the connection dropped and the runtime signalled cancellation.

Common situations: Upstream client disconnects mid-generation; request timeout policy cancels the exchange; user aborts a long-running completion; runtime shutdown cancels all active inferences.

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/1aa4a32dca5b0265. Report an issue: GitHub.

Appendix: source

Thrown at dotnet/src/CopilotRequestHandler.cs:730

    /// <summary>
    /// Request body bytes, yielded as they arrive. A cancel frame surfaces as an
    /// <see cref="OperationCanceledException"/> so the consumer's upstream call
    /// is torn down.
    /// </summary>
    internal IAsyncEnumerable<ReadOnlyMemory<byte>> RequestBody => ReadBodyAsync(Abort.Token);

    private async IAsyncEnumerable<ReadOnlyMemory<byte>> ReadBodyAsync(
        [EnumeratorCancellation] CancellationToken cancellationToken = default)
    {
        while (await _body.Reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false))
        {
            while (_body.Reader.TryRead(out var item))
            {
                if (item.Cancel)
                {
                    _body.Writer.TryComplete();
                    throw new OperationCanceledException(
                        item.CancelReason is null
                            ? "Request cancelled by runtime"
                            : $"Request cancelled by runtime: {item.CancelReason}");
                }

                if (item.End)
                {
                    _body.Writer.TryComplete();
                    yield break;
                }

                if (item.Chunk is { Length: > 0 })
                {
                    yield return item.Chunk;
                }
            }
        }
    }

View on GitHub (pinned to cd8cf15dc3)