github/copilot-sdk · error · InvalidOperationException
LLM inference request was cancelled by the runtime.
Error message
LLM inference request was cancelled by the runtime.
What it means
LlmInferenceExchange.WriteChunkAsync refuses to write body chunks once the runtime has cancelled the request (_cancelled set). This InvalidOperationException prevents writing data for an aborted exchange and preserves protocol ordering (chunks only after StartAsync).
Solutions
- Check the cancelled state (and observe OperationCanceledException) and stop writing immediately
- Abort/complete the write pipeline upon cancellation instead of continuing to enqueue chunks
- Ensure StartAsync is awaited before any WriteAsync call (separate pre-start error)
Example fix
// before
foreach (var chunk in chunks) await exchange.WriteAsync(chunk);
// after
foreach (var chunk in chunks)
{
if (exchange.IsCancelled) break; // stop writing after cancellation
await exchange.WriteAsync(chunk);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (exchange.IsCancelled) return; // do not write after cancellation
Type guard
bool CanWrite(LlmInferenceExchange ex) => !ex.IsCancelled && ex.Started;
Try / catch
try { await exchange.WriteAsync(chunk); }
catch (InvalidOperationException ex) when (ex.Message.Contains("cancelled by the runtime")) { /* stop streaming; dispose exchange */ } Prevention
- Check cancelled state before each chunk write
- Complete the write pipeline on cancellation
- Ensure StartAsync precedes WriteAsync
- Never swallow cancellation exceptions upstream of writes
When it happens
Trigger: Writing response chunks after cancellation was observed, e.g. continuing a chunk-write loop after an OperationCanceledException was caught, or queuing buffered writes that flush after cancellation; also thrown if WriteAsync is called before StartAsync (different message).
Common situations: A producer task keeps streaming into the response after the runtime aborted the request; app buffers chunks and flushes too late; cancellation was swallowed earlier so writes continue silently.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Request cancelled by runtime
- Request cancelled by runtime
- Copilot request was cancelled by the runtime.
- Request cancelled by runtime
- LLM inference request was cancelled by the runtime
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/1a66ad3475667b99.
Report an issue: GitHub.
Appendix: source
Thrown at dotnet/src/CopilotRequestHandler.cs:815
{
return;
}
_finished = true;
await ServerRpc()
.LlmInference.HttpResponseChunkAsync(
RequestId,
string.Empty,
end: true,
error: new LlmInferenceHttpResponseChunkError { Message = message, Code = code })
.ConfigureAwait(false);
}
private async Task WriteChunkAsync(string data, bool binary)
{
if (_cancelled)
{
throw new InvalidOperationException("LLM inference request was cancelled by the runtime.");
}
if (!_started)
{
throw new InvalidOperationException("LLM inference response WriteAsync() called before StartAsync().");
}
if (_finished)
{
throw new InvalidOperationException("LLM inference response WriteAsync() called after EndAsync()/ErrorAsync().");
}
await ServerRpc()
.LlmInference.HttpResponseChunkAsync(RequestId, data, binary: binary, end: false)
.ConfigureAwait(false);
}
private ServerRpc ServerRpc() =>View on GitHub (pinned to cd8cf15dc3)