unslothai/unsloth · warning · TranscriptUnavailable
This video has no captions.
Error message
This video has no captions.
What it means
TranscriptUnavailable raised when the player response contains a captions.playerCaptionsTracklistRenderer with no captionTracks entries that have a baseUrl. The video exists and plays, but YouTube exposes no caption tracks for it — no human subtitles and no auto-generated (ASR) track.
Source
Thrown at studio/backend/core/youtube_transcript.py:124
Within a language a human-written track wins over an auto-generated one. With no
match the track YouTube pairs with the video's default audio track is used.
"""
if not _VIDEO_ID_RE.fullmatch(video_id):
raise TranscriptUnavailable("That is not a YouTube video link.")
async with httpx.AsyncClient(timeout = _TIMEOUT, follow_redirects = True) as client:
player = await _fetch_player(client, video_id)
status = (player.get("playabilityStatus") or {}).get("status")
if status not in (None, "OK"):
raise TranscriptUnavailable(
(player.get("playabilityStatus") or {}).get("reason")
or "YouTube will not play this video."
)
tracklist = (player.get("captions") or {}).get("playerCaptionsTracklistRenderer") or {}
tracks = [t for t in (tracklist.get("captionTracks") or []) if t.get("baseUrl")]
if not tracks:
raise TranscriptUnavailable("This video has no captions.")
track = _select_track(tracks, tracklist, languages)
text = await _fetch_track_text(client, str(track["baseUrl"]))
if not text:
raise TranscriptUnavailable("This video's captions are empty.")
text, truncated = _truncate_transcript(text)
details = player.get("videoDetails") or {}
return Transcript(
video_id = video_id,
title = str(details.get("title") or ""),
author = str(details.get("author") or ""),
length_seconds = _as_int(details.get("lengthSeconds")),
language = _track_label(track),
language_code = str(track.get("languageCode") or ""),
is_generated = track.get("kind") == "asr",
text = text,View on GitHub (pinned to 203007d190)
Solutions
- Confirm the video shows a CC button on YouTube's watch page; if not, no transcript exists — skip it.
- If the video is new, retry later once auto-captions may have been generated.
- Use an alternative transcript source (whisper-based local transcription) when YouTube has none.
Example fix
# before
transcript = await fetch_transcript(video_id)
# after
try:
transcript = await fetch_transcript(video_id)
except TranscriptUnavailable as exc:
transcript = await transcribe_locally(video_id) # fallback, e.g. whisper Defensive patterns
Strategy: fallback
Try / catch
try:
transcript = await fetch_transcript(video_id)
except TranscriptUnavailable as e:
if "no captions" in str(e):
transcript = await transcribe_audio_locally(video_id) # e.g. whisper
else:
raise Prevention
- Pre-filter with the oembed/has_cc signal if available, or accept that some videos have no captions.
- Build UIs to surface 'no captions' as an expected outcome, not a crash.
- Retry later for fresh uploads where ASR may still be generating.
When it happens
Trigger: Videos where the uploader disabled subtitles and auto-captions have not been generated (or were turned off); music-heavy or non-speech videos where ASR produced nothing; tracks present but all missing baseUrl (filtered out).
Common situations: Auto-transcription features pointed at music videos, gameplay with no speech, or freshly uploaded videos where ASR is still processing; rare player-response shape changes dropping captionTracks.
Related errors
- load timed out (last progress: {prog})
- That is not a YouTube video link.
- YouTube will not play this video.
- This video's captions are empty.
- YouTube returned an unreadable response.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/d1823d92edfbbcc0.
Report an issue: GitHub.