{"record":{"id":"0f3030d3dc5971f9","repo":"vercel/ai","slug":"the-operation-was-aborted","errorCode":null,"errorMessage":"The operation was aborted.","messagePattern":"The operation was aborted\\.","errorType":"exception","errorClass":"DOMException","httpStatus":null,"severity":"error","filePath":"packages/code-mode/src/tool-invocation.ts","lineNumber":259,"sourceCode":"  const onAbort = () => {\n    rejectOnAbort(abortReason(abortSignal));\n  };\n\n  abortSignal.addEventListener('abort', onAbort, { once: true });\n  if (abortSignal.aborted) {\n    onAbort();\n  }\n\n  try {\n    return await Promise.race([operation, aborted]);\n  } finally {\n    abortSignal.removeEventListener('abort', onAbort);\n  }\n}\n\nfunction throwIfAborted(abortSignal: AbortSignal | undefined): void {\n  if (abortSignal?.aborted) {\n    throw abortReason(abortSignal);\n  }\n}\n\nfunction abortReason(abortSignal: AbortSignal): unknown {\n  return (\n    abortSignal.reason ??\n    new DOMException('The operation was aborted.', 'AbortError')\n  );\n}\n","sourceCodeStart":241,"sourceCodeEnd":269,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/code-mode/src/tool-invocation.ts#L241-L269","documentation":"Before invoking a host tool (or during a race against an abort signal) in code-mode, the code checks the AbortSignal and throws if it has already fired. The thrown reason is the signal's reason if present, otherwise an 'The operation was aborted.' error. This is the standard cancellation mechanism for tool invocations.","triggerScenarios":"AbortSignal.abort() called (e.g. via AbortController.abort(), timeout, or user cancellation) before or during invokeHostTool / raceAgainstAbort in a code-mode tool invocation.","commonSituations":"Request cancellations from clients disconnecting; tool invocation timeouts; explicit abort of long-running host tool calls; race conditions where abort fires before the tool starts.","solutions":["Check and respect abortSignal.reason to distinguish custom abort causes.","Catch and handle the abort error in the calling code and clean up (this is expected cancellation, not a bug).","If aborts are unintended, audit the AbortController wiring/timeouts passed to the tool invocation.","Pass a properly-scoped AbortSignal (e.g. request-scoped) instead of a long-lived already-aborted signal."],"exampleFix":"// before\nconst result = await invokeHostTool(tool, args); // throws on abort\n// after\ntry {\n  const result = await invokeHostTool(tool, args, { abortSignal });\n} catch (e) {\n  if (abortSignal.aborted) return; // handle cancellation gracefully\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"if (abortSignal?.aborted) {\n  // skip invocation entirely or return a cancellation result early\n}","typeGuard":"function isAbortError(e: unknown): boolean {\n  return e instanceof Error && e.name === 'AbortError';\n}","tryCatchPattern":"try {\n  await invokeHostTool(tool, args, { abortSignal });\n} catch (e) {\n  if (isAbortError(e) || abortSignal?.aborted) return; // expected cancellation\n  throw e;\n}","preventionTips":["Check signal.aborted before starting expensive tool calls","Propagate request-scoped AbortSignals end-to-end","Distinguish timeout aborts (signal.reason) from user cancellations in logs"],"tags":["abort","cancellation","tools","async"],"backgroundTag":"operation-aborted","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}