github/copilot-sdk · warning
Request cancelled by runtime
Error message
Request cancelled by runtime: ${item.cancel.reason} What it means
The handler's request-body stream is fed by the runtime over the bridge; when the runtime cancels the request it enqueues a cancel marker into the buffer. When requestBody() dequeues that marker it stops draining and throws, carrying the runtime's cancellation reason when one was provided. This surfaces cancellation to the handler's body-reading loop.
Solutions
- Wrap the request-processing flow in try/catch and treat cancellation as normal termination: stop work, clean up, and do not attempt further writes.
- Check the handler's cancellation state before/after expensive operations and bail out early instead of waiting for the next read to throw.
- Keep body reads timely; don't block long before reading so cancellation is noticed promptly.
- Log item.cancel.reason context (connection closed vs timeout) to distinguish user aborts from runtime timeouts.
Example fix
// before
for await (const chunk of handler.requestBody()) { await slowProcess(chunk); }
// after
try {
for await (const chunk of handler.requestBody()) {
if (handler.isCancelled) break;
await slowProcess(chunk);
}
} catch (e) {
if (String(e.message).startsWith('Request cancelled by runtime')) return; // normal abort
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
function isRuntimeCancellation(e: unknown): boolean {
return e instanceof Error && e.message.startsWith('Request cancelled by runtime');
} Type guard
const isCancellationError = (e: unknown): e is Error => e instanceof Error && /Request cancelled by runtime/.test(e.message);
Try / catch
try {
for await (const chunk of handler.requestBody()) { await handle(chunk); }
} catch (e) {
if (isCancellationError(e)) { await cleanup(); return; } // expected abort
throw e;
} Prevention
- Poll the handler's cancelled state between expensive operations.
- Keep request processing short and responsive to reads.
- Log cancel reasons to distinguish disconnects from timeouts.
- Clean up resources (streams, temp files) on cancellation.
When it happens
Trigger: The Copilot runtime cancels the in-flight request (client disconnect, timeout, explicit cancel) while the handler is still reading request body chunks; the next requestBody() pull dequeues the cancel item and throws.
Common situations: Client closed the WebSocket connection mid-stream; request exceeded a runtime timeout; handler performs slow work (long awaits between reads) while the user aborts the request.
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
- Request cancelled by runtime
- Copilot request was cancelled by the runtime.
- Request cancelled by runtime
- LLM inference request was cancelled by the runtime
- Request cancelled by runtime
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/1ededa7c919263a7.
Report an issue: GitHub.
Appendix: source
Thrown at nodejs/src/copilotRequestHandler.ts:557
* Request body bytes, yielded as they arrive. A cancel frame surfaces as a
* thrown error so the handler's upstream call is torn down.
*/
get requestBody(): AsyncIterable<Uint8Array> {
return {
[Symbol.asyncIterator]: (): AsyncIterator<Uint8Array> => ({
next: async (): Promise<IteratorResult<Uint8Array>> => {
if (this.#drained) {
return { value: undefined, done: true };
}
while (this.#buffer.length === 0) {
await new Promise<void>((resolve) => {
this.#waker = resolve;
});
}
const item = this.#buffer.shift()!;
if (item.cancel) {
this.#drained = true;
throw new Error(
item.cancel.reason
? `Request cancelled by runtime: ${item.cancel.reason}`
: "Request cancelled by runtime"
);
}
if (item.end) {
this.#drained = true;
return { value: undefined, done: true };
}
return { value: item.chunk ?? new Uint8Array(), done: false };
},
}),
};
}
// --- Response emit (driven by the handler). Strict state machine: ---
// startResponse once -> 0..N writeResponse -> exactly one of
// endResponse / errorResponse.View on GitHub (pinned to cd8cf15dc3)