BoundaryML/baml · warning · BamlAbortError
Operation was aborted
Error message
Operation was aborted
What it means
A BamlAbortError with message 'Operation was aborted' is thrown by the stream's driveToCompletion when the AbortSignal passed to the streaming call has fired. The library checks the signal before consuming further FFI stream events and surfaces the abort as a typed error. It indicates the caller cancelled the operation, not a BAML/provider failure.
Source
Thrown at engine/language_client_typescript/typescript_src/stream.ts:36
private finalCoerce: (result: any) => FinalOutputType,
private ctxManager: RuntimeContextManager,
abortSignal?: AbortSignal,
) {
this.abortSignal = abortSignal;
// Listen for abort to clean up
if (abortSignal) {
abortSignal.addEventListener("abort", () => {
this.eventQueue.push(null); // Signal end of stream
});
}
}
private async driveToCompletion(): Promise<FunctionResult> {
try {
// Check for early abort
if (this.abortSignal?.aborted) {
throw new BamlAbortError(
"Operation was aborted",
this.abortSignal.reason,
);
}
this.ffiStream.onEvent(
(err: Error | null, data: FunctionResult | null) => {
if (err) {
this.error = err;
return;
}
this.eventQueue.push(data);
},
);
const retval = await this.ffiStream.done(this.ctxManager);
View on GitHub (pinned to bd85ce9dee)
Solutions
- Catch BamlAbortError separately and treat it as expected cancellation rather than a failure.
- Check that you did not abort the controller prematurely (e.g. setTimeout or request teardown firing early).
- If partial output is useful, consume stream events incrementally instead of only awaiting the final result.
- Remove or correctly scope the abortSignal if the stream should run to completion.
Example fix
// before
const result = await b.ExtractStory(streamOpts) // unhandled abort
// after
try {
const result = await b.ExtractStory({ abortSignal: controller.signal })
} catch (e) {
if (e instanceof BamlAbortError) return null // cancelled
throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
// before streaming: if (controller.signal.aborted) return null // skip the call entirely
Try / catch
try {
const result = await b.ExtractStory({ abortSignal: controller.signal })
} catch (e) {
if (e instanceof BamlAbortError || e.name === 'BamlAbortError') {
return null // expected cancellation
}
throw e
} Prevention
- Only pass an abortSignal when cancellation is actually desired.
- Distinguish timeouts from user cancels via the signal's reason.
- Consume stream increments if partial output matters before abort.
When it happens
Trigger: Calling a b.stream.* function with an options.abortSignal whose .aborted becomes true (or was already true) while the result is being driven to completion.
Common situations: Request timeouts via AbortController.timeout(); user cancels in a UI; server request context (e.g. Next.js/Hono) aborts on client disconnect; stopping an agent loop early.
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
- AbortError: {detailed_message}
- BamlAbortError: Operation was aborted: {msg}
- AbortError: {detailed_message}
- ExposedError::AbortError { detailed_message }
- -32800
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/9051b6c4cac6b973.
Report an issue: GitHub.