mastra-ai/mastra · info
The operation was aborted.
Error message
The operation was aborted.
What it means
withRetry retries transient LLM failures up to RETRY_CONFIG.maxRetries and throws Error('The operation was aborted.') when the AbortSignal is already aborted before an attempt (or rethrows AbortErrors from fn). It stops retry loops promptly on cancellation instead of burning attempts.
Source
Thrown at packages/memory/src/processors/observational-memory/retry.ts:182
/** Optional abort signal — cancels both in-flight attempts and backoff waits. */
abortSignal?: AbortSignal;
}
/**
* Run `fn` with retries on transient transport-class errors.
*
* Non-transient errors (auth, validation, schema, etc.) are rethrown
* immediately. User-initiated aborts are rethrown without delay.
*
* @internal
*/
export async function withRetry<T>(fn: () => Promise<T>, opts: WithRetryOptions): Promise<T> {
const { label, abortSignal } = opts;
let attempt = 0;
// total tries = maxRetries + 1 (the initial attempt isn't a "retry")
while (true) {
if (abortSignal?.aborted) {
throw new Error('The operation was aborted.');
}
try {
return await fn();
} catch (error) {
if (isAbortError(error) || abortSignal?.aborted) throw error;
if (attempt >= RETRY_CONFIG.maxRetries || !isTransientLLMError(error)) {
if (attempt > 0) {
omDebug(
`[OM:retry:${label}] giving up after ${attempt} retry/retries: ${
error instanceof Error ? error.message : String(error)
}`,
);
}
throw error;
}
const delay = computeDelay(attempt);
attempt++;
omDebug(View on GitHub (pinned to 75dd419e61)
Solutions
- Confirm the abort was intended (timeout/disconnect) via signal reason and logging
- Increase the timeout that triggers the abort if reflections legitimately take longer
- Retry the operation with a fresh, non-aborted signal
- Catch and treat as cooperative cancellation in the caller
Example fix
// before
const signal = AbortSignal.timeout(30_000);
await withRetry(doGenerate, { label: 'reflect', abortSignal: signal });
// after
const signal = AbortSignal.timeout(120_000); // raise budget
await withRetry(doGenerate, { label: 'reflect', abortSignal: signal }); Defensive patterns
Strategy: retry
Validate before calling
if (opts.abortSignal?.aborted) skipOperation();
Type guard
const isAbortErr = (e: unknown) => e instanceof Error && (e.name === 'AbortError' || /aborted/i.test(e.message));
Try / catch
try { await withRetry(fn, opts) } catch (e) { if (opts.abortSignal?.aborted) return; throw e; } Prevention
- Set realistic timeouts before aborting LLM calls
- Reuse a single cancellation scope per request
- Log abort reasons for diagnosis
When it happens
Trigger: The abortSignal passed in opts is aborted before an attempt starts, or fn throws an AbortError / the signal aborts while awaiting fn, while generating reflector output (doGenerate).
Common situations: Request deadline exceeded during LLM retries; caller cancelled a long reflection; infrastructure-level timeouts propagating AbortSignals into the retry loop.
Related errors
- Factory kickoff run was aborted before it finished.
- Login cancelled
- AbortError
- Authentication for MCP server ${serverName} was cancelled.
- Request timed out after ${effectiveTimeout}ms
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/3f3d117f0f1849b7.
Report an issue: GitHub.