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

  1. Check `abortSignal?.aborted` before invoking the agent/memory call and skip observer processing (return early) instead of starting work that will throw.
  2. 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.
  3. If you actually want the work to complete, do not pass an `abortSignal` (it is optional) or pass `AbortSignal.any([...])` excluding the cancelling source.
  4. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/64a333afb3549e60. Report an issue: GitHub.