vercel/ai · error

Transcription failed: ${transcript.error ?? 'Unknown error'}

Error message

Transcription failed: ${transcript.error ?? 'Unknown error'}

What it means

After polling, if AssemblyAI reports transcript.status === 'error', the model throws an Error embedding the provider's transcript.error message (or 'Unknown error'). This means the transcription job itself failed on AssemblyAI's side (e.g. audio unreadable), not a transport problem.

Source

Thrown at packages/assemblyai/src/assemblyai-transcription-model.ts:328

          }),
          requestBodyValues: {},
        });
      }

      const rawTranscript = await response.json();
      const transcript =
        assemblyaiTranscriptionResponseSchema.parse(rawTranscript);

      if (transcript.status === 'completed') {
        return {
          transcript,
          rawTranscript,
          responseHeaders: extractResponseHeaders(response),
        };
      }

      if (transcript.status === 'error') {
        throw new Error(
          `Transcription failed: ${transcript.error ?? 'Unknown error'}`,
        );
      }

      await new Promise(resolve => setTimeout(resolve, pollingInterval));
    }
  }

  async doGenerate(
    options: Parameters<TranscriptionModelV4['doGenerate']>[0],
  ): Promise<Awaited<ReturnType<TranscriptionModelV4['doGenerate']>>> {
    const currentDate = this.config._internal?.currentDate?.() ?? new Date();

    const { value: uploadResponse } = await postToApi({
      url: this.config.url({
        path: '/v2/upload',
        modelId: '',
      }),

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Read the full message for transcript.error and check AssemblyAI's error docs for that code.
  2. Re-upload valid, non-empty audio in a supported format (mp3, wav, flac, m4a, etc.).
  3. Verify the uploaded file's URL is publicly reachable if using upload_url.
  4. Retry only if the error is transient (e.g. internal provider failure).

Example fix

// before
const { transcript } = await model.transcript({ transcriptId }); // throws on status 'error'
// after
const { transcript } = await model.transcript({ transcriptId }).catch(e => {
  console.error('AssemblyAI job failed:', e.message);
  throw e;
});
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const { transcript } = await model.transcript({ transcriptId });
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Transcription failed:')) {
    const providerReason = e.message.replace('Transcription failed: ', '');
    logger.error({ transcriptId, providerReason }, 'AssemblyAI job failed');
    return { ok: false, reason: providerReason };
  }
  throw e;
}

Prevention

When it happens

Trigger: waitForCompletion polls GET /v2/transcript/{id} and the response body has status:'error' — e.g. corrupt/empty audio upload, unsupported format, or failed language detection.

Common situations: Uploading an empty or truncated audio file; unsupported codec; audio too short; provider-side processing failure.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/a52f9afd89f77c8c. Report an issue: GitHub.