unslothai/unsloth · error · TranscriptUnavailable
YouTube returned unreadable caption data.
Error message
YouTube returned unreadable caption data.
What it means
TranscriptUnavailable raised when the caption response body cannot be decoded as UTF-8 or parsed as JSON. Analogous to error 789 but for the caption json3 payload: bytes were received and non-empty, but json.loads fails (UnicodeDecodeError/ValueError, chained from the original error).
Source
Thrown at studio/backend/core/youtube_transcript.py:283
location = response.headers.get("location")
if response.is_redirect and location:
url = urljoin(url, location)
_validated_caption_url(url)
continue
response.raise_for_status()
body = await _read_capped(
response, _MAX_CAPTION_BYTES, "This video's captions are too large to attach."
)
break
else:
raise TranscriptUnavailable("YouTube redirected the caption request too many times.")
if not body:
raise TranscriptUnavailable("YouTube returned no caption text for this video.")
try:
payload = json.loads(body.decode("utf-8"))
except (UnicodeDecodeError, ValueError) as error:
raise TranscriptUnavailable("YouTube returned unreadable caption data.") from error
events = payload.get("events") if isinstance(payload, dict) else None
return _flatten_events(events or [])
def _flatten_events(events: list[Any]) -> str:
lines: list[str] = []
for event in events:
if not isinstance(event, dict):
continue
# aAppend cues carry only the rolling-window newline between ASR lines.
if event.get("aAppend") == 1:
continue
segments = event.get("segs")
if not isinstance(segments, list):
continue
joined = "".join(
str(segment.get("utf8") or "") for segment in segments if isinstance(segment, dict)
)View on GitHub (pinned to 203007d190)
Solutions
- Retry with backoff or a different egress IP.
- Log body[:200] to identify what was actually returned; HTML indicates blocking/consent issues rather than a parse bug.
- Slow down request rates to avoid triggering block pages.
Defensive patterns
Strategy: retry
Try / catch
for attempt in range(2):
try:
transcript = await fetch_transcript(video_id)
break
except TranscriptUnavailable as e:
if "unreadable caption data" in str(e) and attempt == 0:
continue
raise Prevention
- Retry unparseable caption payloads once before failing the video.
- Log a body snippet on failure to distinguish block pages from corruption.
- Avoid aggressive parallel fetching that triggers soft-blocks on caption URLs.
When it happens
Trigger: Caption endpoint returning HTML (error/consent page) or binary/garbage content instead of json3; truncated bodies; encoding mismatches. Distinct from 793 (empty body) — here the body is present but unparseable.
Common situations: Soft-blocks or interstitials served on the caption URL; transient payload corruption; proxy interference.
Related errors
- YouTube returned an unreadable response.
- YouTube will not play this video.
- YouTube redirected the caption request too many times.
- load timed out (last progress: {prog})
- That is not a YouTube video link.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/a4e321bfe85c2ac2.
Report an issue: GitHub.