mastra-ai/mastra · warning
The operation was aborted.
Error message
The operation was aborted.
What it means
The Observational Memory observer runner wraps the Observer agent's model call in `withAbortCheck`, which throws this plain Error when the caller-supplied `AbortSignal` is already aborted before the call starts (observer-runner.ts:185). It is the library's way of canceling observational-memory work early instead of spending tokens on a generation whose result will be discarded. It mirrors the standard DOM/AbortController cancellation contract, but is raised as a synchronous pre-flight check rather than coming from the provider.
Source
Thrown at packages/memory/src/processors/observational-memory/observer-runner.ts:185
* the provider capabilities registry is consulted to decide whether the
* model accepts multimodal input.
*/
private resolveAttachmentFilter(
model: ConcreteObservationModel,
requestContext?: RequestContext,
): ObserverAttachmentFilter {
const raw = this.observationConfig.observeAttachments;
if (raw !== 'auto') return raw;
const routerId = this.extractModelRouterId(model, requestContext);
if (!routerId) return true; // can't determine — default to forwarding
const supports = modelSupportsAttachments(routerId);
return supports ?? true;
}
private async withAbortCheck<T>(fn: () => Promise<T>, abortSignal?: AbortSignal): Promise<T> {
if (abortSignal?.aborted) {
throw new Error('The operation was aborted.');
}
const result = await fn();
if (abortSignal?.aborted) {
throw new Error('The operation was aborted.');
}
return result;
}
/**
* Call the Observer agent for a single thread.
*/
async call(
existingObservations: string | undefined,
messagesToObserve: MastraDBMessage[],
abortSignal?: AbortSignal,
options?: {
skipContinuationHints?: boolean;
requestContext?: RequestContext;View on GitHub (pinned to 75dd419e61)
Solutions
- Check `abortSignal?.aborted` before invoking the agent/memory call and skip observer processing (return early) instead of starting work that will throw.
- Ensure each agent run uses its own AbortController rather than sharing one signal across sequential operations (generation, then memory), so an abort from one phase doesn't pre-abort the next.
- If you actually want the work to complete, do not pass an `abortSignal` (it is optional) or pass `AbortSignal.any([...])` excluding the cancelling source.
- Catch this error in the caller and treat it as a benign cancellation (e.g. rethrow `AbortError` or log-and-return) so cancelled requests don't surface as failures.
Example fix
// before
await agent.generate(messages, {
abortSignal: sharedController.signal, // already aborted by a previous cancelled request
});
// after
if (controller.signal.aborted) {
return; // skip memory processing for cancelled requests
}
await agent.generate(messages, {
abortSignal: controller.signal,
}); Defensive patterns
Strategy: try-catch
Validate before calling
if (signal?.aborted) {
// don't start memory processing at all
return skipObservation();
} Type guard
function isAborted(signal?: AbortSignal): boolean {
return signal?.aborted === true;
} Try / catch
try {
await memory.process(messages, { abortSignal: signal });
} catch (err) {
if (err instanceof Error && err.message === 'The operation was aborted.') return; // benign cancellation
throw err;
} Prevention
- Always check `signal.aborted` before invoking memory/agent APIs.
- Use a fresh AbortController per agent run instead of sharing signals across phases.
- Use `AbortSignal.any([...])` to compose only the sources you intend to cancel on.
- Treat 'The operation was aborted.' as cancellation, not failure, in error handling.
When it happens
Trigger: Calling memory retrieval/processing (e.g. via `ObservationalMemory` processor inside an agent run) with an `abortSignal` that is already in the `aborted` state when `ObserverRunner.call` -> `doGenerate` -> `withAbortCheck` runs. Typically the request that triggered memory processing was cancelled before the observer step began.
Common situations: A client disconnects from an HTTP request and the server aborts the controller before memory processing starts; a timeout (AbortSignal.timeout) fires before the observer call; a UI cancels a previous in-flight agent generation whose shared signal is reused for memory work; passing `req.signal` from an already-finished request.
Related errors
- The operation was aborted.
- Login cancelled
- Login cancelled
- CreateCancelledError (Operation cancelled)
- CreateCancelledError
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/64a333afb3549e60.
Report an issue: GitHub.