{"record":{"id":"8871bc2772710f17","repo":"unslothai/unsloth","slug":"str-error","errorCode":null,"errorMessage":"str(error)","messagePattern":"str\\(error\\)","errorType":"http","errorClass":"HTTPException","httpStatus":422,"severity":"error","filePath":"studio/backend/routes/youtube.py","lineNumber":62,"sourceCode":"    language: str\n    languageCode: str\n    isGenerated: bool\n    text: str\n    truncated: bool\n\n\n@router.post(\"/transcript\", response_model = TranscriptResponse)\nasync def get_transcript(\n    request: TranscriptRequest, current_subject: str = Depends(get_current_subject)\n) -> TranscriptResponse:\n    video_id = extract_video_id(request.url)\n    if video_id is None:\n        raise HTTPException(status_code = 400, detail = \"That is not a YouTube video link.\")\n\n    try:\n        transcript = await fetch_transcript(video_id, request.languages)\n    except TranscriptUnavailable as error:\n        raise HTTPException(status_code = 422, detail = str(error)) from error\n    except httpx.HTTPError as error:\n        logger.warning(f\"YouTube transcript fetch failed for {video_id}: {error}\")\n        raise HTTPException(\n            status_code = 502,\n            detail = \"Could not reach YouTube.\",\n        ) from error\n\n    return TranscriptResponse(\n        videoId = transcript.video_id,\n        url = watch_url(transcript.video_id),\n        title = transcript.title,\n        author = transcript.author,\n        lengthSeconds = transcript.length_seconds,\n        language = transcript.language,\n        languageCode = transcript.language_code,\n        isGenerated = transcript.is_generated,\n        text = transcript.text,\n        truncated = transcript.truncated,","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/youtube.py#L44-L80","documentation":"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.","triggerScenarios":"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.","commonSituations":"Music videos and game captures (captions routinely absent); non-matching language preference lists; freshly uploaded videos.","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."],"exampleFix":"// before\nawait api.post('/youtube/transcript', { url, languages: ['de'] });\n\n// after\ntry {\n  await api.post('/youtube/transcript', { url, languages: ['de'] });\n} catch (e) if (e.status === 422) {\n  // fall back to any available language\n  await api.post('/youtube/transcript', { url });\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await api.post('/youtube/transcript', { url, languages });\n} catch (e) {\n  if (e.status === 422 && languages?.length) {\n    // language miss: accept any available track\n    return await api.post('/youtube/transcript', { url });\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["http-422","youtube","transcript","captions","content-unavailable"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}