vercel/ai · info
Transcription request was aborted
Error message
Transcription request was aborted
What it means
AssemblyAI transcription polling loop checks the caller-supplied abortSignal before each status-polling GET. If the signal is already aborted, it throws this generic Error instead of continuing to poll. It exists so callers can cancel long-running transcription waits (which can take minutes).
Source
Thrown at packages/assemblyai/src/assemblyai-transcription-model.ts:286
private async waitForCompletion(
transcriptId: string,
headers: Record<string, string | undefined> | undefined,
abortSignal?: AbortSignal,
): Promise<{
transcript: z.infer<typeof assemblyaiTranscriptionResponseSchema>;
rawTranscript: unknown;
responseHeaders: Record<string, string>;
}> {
const pollingInterval =
this.config.pollingInterval ?? this.POLLING_INTERVAL_MS;
// Honor a caller-provided fetch (proxy, auth injection, tests) for the
// polling GETs, matching the upload/submit calls that use config.fetch.
const fetchImpl = this.config.fetch ?? globalThis.fetch;
while (true) {
if (abortSignal?.aborted) {
throw new Error('Transcription request was aborted');
}
const response = await fetchImpl(
this.config.url({
path: `/v2/transcript/${transcriptId}`,
modelId: this.modelId,
}),
{
method: 'GET',
headers: combineHeaders(
this.config.headers?.(),
headers,
) as HeadersInit,
signal: abortSignal,
},
);
if (!response.ok) {View on GitHub (pinned to 69428b1f8b)
Solutions
- Pass a fresh AbortController signal only if you actually want cancellation.
- Check signal.aborted before calling and skip transcription if already aborted.
- Wrap the call in try/catch and treat this error as an intentional cancel, not a failure.
- Increase or remove upstream timeouts that abort the shared signal prematurely.
Example fix
// before
const result = await model.transcript({ transcriptId, abortSignal: controller.signal });
// after
try {
const result = await model.transcript({ transcriptId, abortSignal: controller.signal });
} catch (e) {
if (controller.signal.aborted) return; // intentional cancellation
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (abortSignal?.aborted) {
// skip the transcription call entirely
return;
} Try / catch
try {
await model.transcript({ transcriptId, abortSignal });
} catch (e) {
if (abortSignal?.aborted || (e instanceof Error && e.message === 'Transcription request was aborted')) {
return; // treat as cancellation
}
throw e;
} Prevention
- Use a dedicated AbortController per transcription request, not a shared one.
- Check signal.aborted before starting long waits.
- Surface cancellation to users distinctly from failures.
When it happens
Trigger: Calling transcript()/rawTranscript() on assemblyai.transcriptionModel with an abortSignal that becomes (or already is) aborted while waitForCompletion polls GET /v2/transcript/{id}.
Common situations: User cancels a UI request mid-transcription; server request shutdown triggers AbortController; a shared signal aborted by an earlier timeout is reused.
Related errors
- AbortError
- Stream aborted
- Transcription failed: ${transcript.error ?? 'Unknown error'}
- MCP client initialization was aborted
- TranscriptionJobPollingTimedOut
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/7295bfc0819ddb26.
Report an issue: GitHub.