Symptom → cause → fix for the failures people actually hit. Two things to try before anything below:
watch-skill doctor— it does not just diagnose, it self-heals: installs missing ffmpeg/yt-dlp/deno into the managed~/.watch-skill/bin/, updates a stale yt-dlp, and checks disk, GPU, and API keys. Most acquisition and dependency failures end here.- Read the
fixfield. Every structured error is{error, message, fix, details}— thefixnames the exact setting, command, or tool to use next.
uv sync fails with os error 32 (file in use) on Windows
A running MCP server (your agent's session) holds a lock on
.venv\Scripts\watch-skill.exe. Close the agent or kill the process
(taskkill /im watch-skill.exe /f), then re-run. For tests and examples
you can skip syncing entirely: uv run --no-sync ....
ffmpeg not found even though you installed it
Package managers (winget, brew) sometimes leave PATH stale in the shell
that launched your agent. Watch Skill prefers its own managed copy:
watch-skill doctor installs ffmpeg into ~/.watch-skill/bin/ and every
surface prepends that directory to PATH, so the managed copy wins
regardless of shell state.
Arabic / CJK titles print as ? in the terminal
Legacy Windows code pages (cp1256 etc.) can't encode every character; the
CLI degrades unprintable characters instead of crashing. The index itself
is always full-fidelity UTF-8 — MCP and REST output is unaffected. For a
correct display, use Windows Terminal or chcp 65001.
The MCP server doesn't show up in your agent
Run watch-skill setup — it detects installed agents and writes the MCP
config (backing up existing files), then restart the agent. Manual
per-agent configs: agents/README.md.
A YouTube/TikTok/... download suddenly fails that worked last week
Extractor breakage — sites change, yt-dlp chases them. Watch Skill
detects the signature, self-updates yt-dlp, and retries once
automatically; if it still fails, run watch-skill doctor (updates
yt-dlp explicitly) and retry. Persistent failures fall through the chain:
yt-dlp → cobalt (only if WATCHSKILL_COBALT_API_URL is set) → direct
ffmpeg pull; the error's details show what each rung said.
A live stream watch never finishes
Bound it: watch-skill watch <url> --duration 60 caps the capture at N
seconds (MCP: pass start/end or budget).
Same URL keeps re-downloading / you need a fresh copy
Downloads land in a content-addressed LRU cache under ~/.watch-skill/.
Re-watching is nearly free; to force a fresh download (e.g. after fixing
caption languages), use --no-cache.
ask returns an evidence list saying the video "does not clearly show"
the answer
Not a bug — the honest floor. Without a vision/LLM provider the engine
returns timestamped evidence instead of synthesizing an answer it can't
verify. Configure any WATCHSKILL_* cloud key or run Ollama with a
vision model to get natural-language verified answers; the evidence-list
mode remains the fallback whenever confidence stays low.
The transcript is an English translation of a non-English video
An old index entry from before original-language captions were preferred,
or the cached download only has English tracks. Re-watch with
watch-skill watch <url> --no-cache; for extra caption tracks set
WATCHSKILL_SUBTITLE_LANGS (see the
Arabic guide).
First transcription of a captionless video is very slow
That's the local whisper model downloading, once. Captions are always
tried first. For text-only speed: --transcript-only; to pin a smaller
model: --whisper-model tiny. Cloud STT is strictly opt-in
(--cloud-stt).
A wrong answer keeps coming back
Two separate mechanisms: (1) --no-cache on ask bypasses the semantic
answer cache for one call, watch-skill clean --cache-answers clears it;
(2) report the mistake (report_mistake tool or watch-skill lessons add) so the correction becomes a lesson applied to future questions —
see the lessons guide.
capture/loop_start on a URL fails to find a browser
The headless capture needs Chromium-family: Edge or Chrome installed, or
playwright install chromium. screen: and window:<title> capture
don't need a browser at all.
The loop critique seems shallow (misses layout issues) No vision provider reachable, so the deterministic OCR critic was selected (the loop machinery is identical). Configure a vision provider for the strong-tier critic; the critic line at loop start tells you which one is active.
window:<title> capture finds nothing
The title must match exactly (it's a live window enumeration). Check the
window's real title bar text, including suffixes like - Notepad.
index.video_not_found / unknown video
The id or source isn't in the index — watch-skill list (MCP:
list_videos) shows what is. Sources match by the original URL/path
exactly as first watched.
Disk usage keeps growing
Bounded, but reclaimable: watch-skill clean --all (cache to its size
cap + old loops + orphaned frame dirs), --dry-run first to see what
would go.
The agent has no watch_* tools, and nothing says why
dsh plugin add writes into the profile you name and the launcher boots the
profile it is given. Installing into one and booting another leaves a working
agent with none of the tools and no error, because nothing went wrong — you are
looking at a different profile. Check what the one you boot actually composes:
dsh --profile <your-profile> --dump-config | grep watch-dsh --profile <name> web boots the wrong thing
There is no web subcommand. dsh web is an alias of dsh --profile web, so
adding web after your own profile name boots your profile and passes web to
the app as an argument. Name the profile once, after --profile, and pass
nothing else.
The Library says empty after a restart, and Refresh does not help
Receipts are journalled under the launch directory, at .watch/receipts. A
Host started somewhere other than your project journals somewhere else, and
Refresh re-reads what is on disk — which, in that directory, is nothing. cd
to your project first, then start it. The receipts were never lost; they are
under the directory the earlier run was launched from.
watch_library_search answers no_roots_configured
That is a different index from the receipt journal, and it is empty by design:
the deployment has not said which directories hold evidence records. Set the
watch-tools row's libraryRoots. The receipt journal needs no such setting.
A provider that worked yesterday needs testing again today The routing guard will not send to a binding no provider test has proved, and a Host restart is a new process with nothing proved in it. Saved is not tested. Run the provider test again; it spends one deliberately tiny request.
watch_moment fails on a Core that is otherwise healthy
Engines before 1.4.3 raise instead of answering: the Bridge tried to iterate its
result instead of serialising it, so every call failed and the Host's own
parameter-name mismatch hid it. pip install -U 'watch-skill[standard,ocr]'.
config.public_bind_no_token on startup
Deliberate: the API refuses to bind non-loopback hosts without auth. Set
WATCHSKILL_API_BEARER_TOKEN (clients send Authorization: Bearer <token>), or keep it on 127.0.0.1.
watch-skill doctor --json prints a machine-readable report of every
check — attach it to a
GitHub issue along with
the failing command and the structured error payload.