Captions are hardcoded to English (--sub-langs "en.*"), so non-English videos return machine-translated transcripts

Author: miguexisCreated Aug 17, 2026Updated Aug 17, 2026

Summary

/watch always asks yt-dlp for English subtitles. For a video spoken in another language that means it silently returns YouTube's auto-translated English track instead of the original-language captions — even when the original is available and free.

This is worse than a wording nit: the translation layer invents content, and the result reads fluently enough that nothing in the output suggests anything is wrong.

Environment

  • watch 0.2.0, installed as a Claude Code plugin from bradautomates/claude-video
  • Windows 11, Python 3.12, yt-dlp present, WATCH_DETAIL=transcript

Where it's hardcoded

skills/watch/scripts/download.py — both yt-dlp call sites:

  • L76-78 (captions-only path) — "--write-subs", "--write-auto-subs", "--sub-langs", "en.*"
  • L133-135 (download path) — same three lines

There is no CLI flag and no environment variable to override it.

A third spot assumes English too — _pick_subtitle() ranks candidates by English filename markers:

python
preferred = [
    c for c in candidates
    if any(marker in c.name for marker in (".en.", ".en-US.", ".en-GB.", ".en-orig."))
]

Reproduction

A 97-second Brazilian Portuguese video that has both pt-orig and an auto-translated en track:

bash
python scripts/watch.py "https://www.youtube.com/watch?v=66oEbJGy8Lc"

The choice is visible in the log, and it's the only hint anything happened:

[info] 66oEbJGy8Lc: Downloading subtitles: en

Now fetch the original track for comparison:

bash
yt-dlp --skip-download --write-auto-subs --sub-langs "pt-orig" \
  "https://www.youtube.com/watch?v=66oEbJGy8Lc"

At 01:12 the two disagree in a way that destroys the meaning:

track text
pt-orig (what was said) "porque aí bate, poupa tempo" — "so you just shoot it, it saves time"
en (what /watch returns) *"because you'll always … Poupatempo (a Brazilian government service center)"*

poupa tempo is two ordinary words meaning "saves time". The translator read it as the proper noun Poupatempo (a real Brazilian government service centre) and then added a parenthetical gloss that does not exist in the source audio at all. The one sentence that states the benefit of the video's advice becomes a reference to a government office.

Why this is hard to catch

  • The report header says Transcript: 39 segments (via captions) — accurate, but it doesn't say which language, so a translated track is indistinguishable from a native one.
  • The English output is grammatical and readable. Machine translation fixes the grammar while breaking the fact, so the usual smell test (garbled text = bad transcript) doesn't fire.
  • The Whisper fallback isn't the answer here: correct captions already exist and are free. Paying an API to work around a hardcoded language parameter would be the wrong fix.

Suggested fix

  1. Make --sub-langs configurable — a CLI flag plus a WATCH_SUB_LANGS key in ~/.config/watch/.env, resolved exactly the way config.py:get_config() already resolves WATCH_DETAIL (env var → .env file → default).
  2. Better default: prefer the video's own language. --write-info-json is already passed, and the resulting video.info.json carries the language — for the video above, info["language"] == "pt". Requesting something like <lang>-orig,<lang>,en.* would prefer the original and keep English as a fallback, with no extra network call.
  3. Report the track that was used — add the subtitle language to the Transcript: line so a translated track is visible to whoever reads the report.
  4. _pick_subtitle() would then need to rank by the requested languages rather than the fixed English marker list.

Happy to open a PR if this approach sounds right to you.

Source: bradautomates/claude-video