dotnet/runtime · error · Error
OperationCanceledException
Error message
OperationCanceledException
What it means
Thrown by http_wasm_get_streamed_response_bytes when the response stream reader reports done (chunk.done) AND controller.isAborted is true. It represents a deliberately-cancelled HTTP read being surfaced to .NET as an OperationCanceledException-equivalent.
Source
Thrown at src/mono/browser/runtime/http.ts:260
const view = new Span(bufferPtr, bufferLength, MemoryViewType.Byte);
return wrap_as_cancelable_promise(async () => {
await controller.responsePromise;
mono_assert(controller.response, "expected response");
if (!controller.response.body) {
// in FF when the verb is HEAD, the body is null
return 0;
}
if (!controller.streamReader) {
controller.streamReader = controller.response.body.getReader();
mute_unhandledrejection(controller.streamReader.closed);
}
if (!controller.currentStreamReaderChunk || controller.currentBufferOffset === undefined) {
controller.currentStreamReaderChunk = await controller.streamReader.read();
controller.currentBufferOffset = 0;
}
if (controller.currentStreamReaderChunk.done) {
if (controller.isAborted) {
throw new Error("OperationCanceledException");
}
return 0;
}
const remaining_source = controller.currentStreamReaderChunk.value.byteLength - controller.currentBufferOffset;
mono_assert(remaining_source > 0, "expected remaining_source to be greater than 0");
const bytes_copied = Math.min(remaining_source, view.byteLength);
const source_view = controller.currentStreamReaderChunk.value.subarray(controller.currentBufferOffset, controller.currentBufferOffset + bytes_copied);
view.set(source_view, 0);
controller.currentBufferOffset += bytes_copied;
if (remaining_source == bytes_copied) {
controller.currentStreamReaderChunk = undefined;
}
return bytes_copied;
});
}View on GitHub (pinned to 290d5ab72c)
Solutions
- Treat OperationCanceledException as expected when a CancellationToken is in play — catch OperationCanceledException in your .NET HttpClient code.
- Ensure you are not aborting requests unintentionally (e.g., disposing the HttpResponseMessage or HttpClient prematurely).
- If aborts are unexpected, audit cancellation token sources for accidental cancellation.
Example fix
// before: unhandled cancellation on streaming response
// var resp = await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, ct);
// await resp.Content.ReadAsStreamAsync(ct); // throws OperationCanceledException
// after: handle cancellation explicitly
try {
var resp = await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, ct);
await ProcessStreamAsync(await resp.Content.ReadAsStreamAsync(ct), ct);
} catch (OperationCanceledException) when (ct.IsCancellationRequested) {
// expected
} Defensive patterns
Strategy: try-catch
Try / catch
try {
await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, ct);
} catch (OperationCanceledException) when (ct.IsCancellationRequested) {
// expected cancellation
} Prevention
- Always handle OperationCanceledException when using CancellationTokens with HttpClient.
- Audit CancellationTokenSource instances for accidental cancellation.
- Do not dispose HttpClient/HttpResponseMessage while reads are in flight.
When it happens
Trigger: Produced when consuming a streamed response body after the request was aborted (http_wasm_abort set controller.isAborted) and the reader has reached the end of the stream.
Common situations: A CancellationToken cancels an HttpClient.SendAsync with streaming response; the abort fires concurrently with the stream finishing; client navigates away during a long download.
Related errors
- BrowserHttpWriteStream.Rejected
- BrowserHttpWriteStream.Rejected
- OperationCanceledException
- Please install `node-fetch` and `node-abort-controller` npm
- This browser doesn't support fetch API. Please use a modern
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/cfab00f64b10808b.
Report an issue: GitHub.