{"record":{"id":"efbf5157ee941346","repo":"remotion-dev/remotion","slug":"invalid-elevenlabs-transcript-the-transcript-must","errorCode":null,"errorMessage":"Invalid ElevenLabs transcript. The transcript must be generated with `timestamps_granularity` set to `\"word\"`. See https://www.remotion.dev/docs/elevenlabs/elevenlabs-transcript-to-captions","messagePattern":"Invalid ElevenLabs transcript\\. The transcript must be generated with `timestamps_granularity` set to `\"word\"`\\. See https://www\\.remotion\\.dev/docs/elevenlabs/elevenlabs-transcript-to-captions","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/elevenlabs/src/elevenlabs-transcript-to-captions.ts","lineNumber":18,"sourceCode":"import type {Caption} from '@remotion/captions';\nimport type {ElevenLabsTranscript} from './elevenlabs-transcript';\n\nexport type ElevenLabsTranscriptToCaptionsInput = {\n\ttranscript: ElevenLabsTranscript;\n};\n\nexport type ElevenLabsTranscriptToCaptionsOutput = {\n\tcaptions: Caption[];\n};\n\nexport const elevenLabsTranscriptToCaptions = ({\n\ttranscript,\n}: ElevenLabsTranscriptToCaptionsInput): ElevenLabsTranscriptToCaptionsOutput => {\n\tconst captions: Caption[] = [];\n\n\tif (!transcript || !transcript.words || !Array.isArray(transcript.words)) {\n\t\tthrow new Error(\n\t\t\t'Invalid ElevenLabs transcript. The transcript must be generated with `timestamps_granularity` set to `\"word\"`. See https://www.remotion.dev/docs/elevenlabs/elevenlabs-transcript-to-captions',\n\t\t);\n\t}\n\n\tconst {words} = transcript;\n\n\tlet isFirst = true;\n\n\tfor (let i = 0; i < words.length; i++) {\n\t\tconst entry = words[i];\n\n\t\tif (entry.type !== 'word') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst prevEntry = i > 0 ? words[i - 1] : null;\n\t\tconst hasSpacing = prevEntry !== null && prevEntry.type === 'spacing';\n","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/elevenlabs/src/elevenlabs-transcript-to-captions.ts#L1-L36","documentation":"The `elevenLabsTranscriptToCaptions` function expects an ElevenLabs transcript object with a `words` array, which is only present when the ElevenLabs API was called with `timestamps_granularity` set to `\"word\"`. If the transcript is null, missing the `words` field, or `words` is not an array, this error is thrown. This typically happens when the transcript was generated with character-level or no granularity.","triggerScenarios":"Calling the function with a transcript from an ElevenLabs API call that used `timestamps_granularity: 'char'`, passing a speech-to-text result from a different provider, or passing an empty/null transcript object.","commonSituations":"Copying an ElevenLabs API response without setting the granularity parameter, switching from character-level to word-level captions without regenerating the transcript, or passing a Deepgram/Whisper result instead of ElevenLabs.","solutions":["Regenerate the transcript with the ElevenLabs API using `timestamps_granularity: 'word'`.","Verify the transcript object has a `words` array before calling the function.","If using a different provider, convert its output to the ElevenLabs transcript shape with a `words` array first."],"exampleFix":"// before\nconst result = await fetch('https://api.elevenlabs.io/v1/speech-to-text', { ... });\nelevenLabsTranscriptToCaptions({ transcript: result });\n\n// after\n// Set timestamps_granularity to 'word' in the API request\nelevenLabsTranscriptToCaptions({ transcript: result }); // now has .words array","handlingStrategy":"type-guard","validationCode":"if (!transcript || !Array.isArray(transcript.words)) {\n  throw new Error('Transcript was not generated with word-level timestamps');\n}\nconst {captions} = elevenLabsTranscriptToCaptions({ transcript });","typeGuard":"const isWordLevelTranscript = (t: unknown): t is { words: unknown[] } =>\n  typeof t === 'object' &&\n  t !== null &&\n  'words' in t &&\n  Array.isArray((t as { words: unknown }).words);","tryCatchPattern":"try {\n  const {captions} = elevenLabsTranscriptToCaptions({ transcript });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('timestamps_granularity')) {\n    // re-request transcript with word-level granularity\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always set timestamps_granularity to 'word' when calling the ElevenLabs speech-to-text API.","Validate the transcript shape before passing to the conversion function.","Store the granularity setting alongside the transcript to detect mismatches early."],"tags":["elevenlabs","captions","validation","api"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}