unslothai/unsloth · error · HTTPException
str(error)
Error message
str(error)
What it means
422 from POST /youtube/transcript: fetch_transcript raised TranscriptUnavailable and the 422 detail is that exception's message. This covers YouTube-side content problems the service distinguishes from network failure: no captions exist for the video, captions exist but none match the requested languages, auto-generated captions are disabled, or the video is private/age-restricted/removed.
Source
Thrown at studio/backend/routes/youtube.py:62
language: str
languageCode: str
isGenerated: bool
text: str
truncated: bool
@router.post("/transcript", response_model = TranscriptResponse)
async def get_transcript(
request: TranscriptRequest, current_subject: str = Depends(get_current_subject)
) -> TranscriptResponse:
video_id = extract_video_id(request.url)
if video_id is None:
raise HTTPException(status_code = 400, detail = "That is not a YouTube video link.")
try:
transcript = await fetch_transcript(video_id, request.languages)
except TranscriptUnavailable as error:
raise HTTPException(status_code = 422, detail = str(error)) from error
except httpx.HTTPError as error:
logger.warning(f"YouTube transcript fetch failed for {video_id}: {error}")
raise HTTPException(
status_code = 502,
detail = "Could not reach YouTube.",
) from error
return TranscriptResponse(
videoId = transcript.video_id,
url = watch_url(transcript.video_id),
title = transcript.title,
author = transcript.author,
lengthSeconds = transcript.length_seconds,
language = transcript.language,
languageCode = transcript.language_code,
isGenerated = transcript.is_generated,
text = transcript.text,
truncated = transcript.truncated,View on GitHub (pinned to 203007d190)
Solutions
- Read the detail message — it states which case applied (no captions vs language mismatch).
- Retry without the languages filter to accept any available track.
- Verify the video is public and has captions (CC button on YouTube's own player).
- If captions genuinely don't exist, no fix is possible — pick another source video.
Example fix
// before
await api.post('/youtube/transcript', { url, languages: ['de'] });
// after
try {
await api.post('/youtube/transcript', { url, languages: ['de'] });
} catch (e) if (e.status === 422) {
// fall back to any available language
await api.post('/youtube/transcript', { url });
} Defensive patterns
Strategy: fallback
Try / catch
try {
return await api.post('/youtube/transcript', { url, languages });
} catch (e) {
if (e.status === 422 && languages?.length) {
// language miss: accept any available track
return await api.post('/youtube/transcript', { url });
}
throw e;
} Prevention
- Show the 422 detail — it distinguishes 'no captions' from 'language mismatch'
- Leave languages empty unless a specific language is required
- Prefer manual captions over auto-generated when both exist; check availability in the YouTube UI first
When it happens
Trigger: Requesting a video with captions disabled by the uploader; requesting languages=['de'] for an English-only video; private/unlisted video whose transcript endpoint returns no body; auto-caption still processing for a just-uploaded video.
Common situations: Music videos and game captures (captions routinely absent); non-matching language preference lists; freshly uploaded videos.
Related errors
- load timed out (last progress: {prog})
- That is not a YouTube video link.
- YouTube will not play this video.
- This video has no captions.
- This video's captions are empty.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/8871bc2772710f17.
Report an issue: GitHub.