{"record":{"id":"ff96344cee3baf49","repo":"vercel/ai","slug":"transcriptionjobpollingtimedout-ff9634","errorCode":"TranscriptionJobPollingTimedOut","errorMessage":"Transcription job polling timed out","messagePattern":"Transcription job polling timed out","errorType":"error_code","errorClass":"AISDKError","httpStatus":null,"severity":"error","filePath":"packages/revai/src/revai-transcription-model.ts","lineNumber":177,"sourceCode":"\n    if (submissionResponse.status === 'failed') {\n      throw new AISDKError({\n        message: 'Failed to submit transcription job to Rev.ai',\n        name: 'TranscriptionJobSubmissionFailed',\n        cause: submissionResponse,\n      });\n    }\n\n    const jobId = submissionResponse.id;\n    const timeoutMs = 60 * 1000; // 60 seconds timeout\n    const startTime = Date.now();\n    const pollingInterval = 1000;\n    let jobResponse = submissionResponse;\n\n    while (jobResponse.status !== 'transcribed') {\n      // Check if we've exceeded the timeout\n      if (Date.now() - startTime > timeoutMs) {\n        throw new AISDKError({\n          message: 'Transcription job polling timed out',\n          name: 'TranscriptionJobPollingTimedOut',\n          cause: submissionResponse,\n        });\n      }\n\n      // Poll for job status\n      const pollingResult = await getFromApi({\n        url: this.config.url({\n          path: `/speechtotext/v1/jobs/${jobId}`,\n          modelId: this.modelId,\n        }),\n        validateUrl: false,\n        headers: combineHeaders(this.config.headers?.(), options.headers),\n        failedResponseHandler: revaiFailedResponseHandler,\n        successfulResponseHandler: createJsonResponseHandler(\n          revaiTranscriptionJobResponseSchema,\n        ),","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/revai/src/revai-transcription-model.ts#L159-L195","documentation":"doGenerate polls Rev.ai's job status every 1000ms until it becomes 'transcribed'; if the elapsed time exceeds timeoutMs, this error is thrown. It means Rev.ai did not finish transcribing within the configured timeout. The last known job response is attached as cause.","triggerScenarios":"Polling loop runs longer than timeoutMs (default configured on the model) because the audio file is very long, Rev.ai is slow/backlogged, or the job is stuck in a non-terminal state.","commonSituations":"Transcribing hours-long audio with the default short timeout; Rev.ai service degradation; a job that permanently stalls (polling loop keeps hitting the timeout check).","solutions":["Increase the transcription model's polling timeout option to cover long audio durations","Inspect the job via error.cause and Rev.ai's dashboard to see whether it completed later","Check Rev.ai status/incidents for outages","Retry the job; if consistently stuck, contact Rev.ai support with the job id"],"exampleFix":"// before\nconst model = revai.transcriptionModel('general');\n// after\nconst model = revai.transcriptionModel('general', { pollTimeoutMs: 15 * 60 * 1000 });","handlingStrategy":"retry","validationCode":"// estimate: ensure timeout exceeds expected transcription time\nconst expectedMs = (audioDurationSeconds / 60) * 15000; // rough budget\nif (timeoutMs < expectedMs) console.warn('Polling timeout likely too short for audio length');","typeGuard":"function isPollingTimeout(e) {\n  return typeof e === 'object' && e !== null && e.name === 'TranscriptionJobPollingTimedOut';\n}","tryCatchPattern":"try {\n  result = await model.doGenerate(options);\n} catch (e) {\n  if (e.name === 'TranscriptionJobPollingTimedOut') {\n    result = await pollJobDirectly(e.cause.jobId); // resume polling with longer budget\n  } else throw e;\n}","preventionTips":["Set a polling timeout proportional to audio duration","Check Rev.ai incident status before long jobs","Persist the job id (from e.cause) so you can resume instead of re-uploading"],"tags":["timeout","polling","transcription","revai"],"backgroundTag":"job-polling-timeout","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}