Files
gui-video-clipper/chat-summaries/2026-09-23_09-58-fix-stale-captions-cross-video-summary.md
cottongin 1b035c9af6 fix: use per-video caption cache dir to prevent cross-video caption bleed
Subtitle downloads were going to a shared /tmp/video-clipper/subtitles/ dir,
so find_vtt_file could return captions from a previously-loaded video. Now
uses cache_manager::caption_cache_dir (URL-hash-keyed) with pre-download
cleanup, matching the existing per-video caching pattern.

Bump to v0.2.2.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-23 06:00:43 -04:00

3.2 KiB

Fix: Stale Captions Persisting Across Different Videos

Date: 2026-09-23
Task: Fix bug where captions from a previously-loaded video were displayed for a newly-loaded video.

Problem

When switching between different YouTube videos, the app would display captions from the first video instead of the current one. The bug manifested because:

  1. Shared flat directory — All subtitle downloads for every video went to the same temp directory: /tmp/video-clipper/subtitles/. Old .vtt files from previous videos persisted there.
  2. Non-specific file lookup — find_vtt_file() in subtitle_downloader.rs scanned the directory and returned the first .en.vtt file it found, regardless of which video it belonged to.
  3. Cache amplification — Once the wrong caption path was returned, save_analysis_to_cache copied that wrong .vtt file into the URL-keyed analysis cache, persisting the error across sessions.

Root Cause

In src-tauri/src/commands/video.rs, the download_subtitles command used a shared temp directory for all videos:

let output_dir = std::env::temp_dir()
    .join("video-clipper")
    .join("subtitles")
    .to_string_lossy()
    .to_string();

This ignored the existing cache_manager::caption_cache_dir(url) function that provides a per-video, URL-hash-keyed cache directory — the same scheme used by thumbnail caching and the analysis cache.

Changes Made

src-tauri/src/commands/video.rs

  • Added import for cache_manager from services
  • Changed download_subtitles to use cache_manager::caption_cache_dir(&url) instead of the shared temp directory
  • Added pre-download cleanup: removes any existing .vtt files in the directory before downloading, ensuring find_vtt_file can only return a file from the current download

What Was NOT Changed

  • subtitle_downloader.rs — already correctly accepts output_dir as a parameter, no changes needed
  • cache_manager.rs — caption_cache_dir() already existed and was correctly implemented
  • Frontend stores — setMetadata() already resets captionFilePath to null on video switch

Important Note

Existing corrupted cache entries (from before this fix) will continue serving wrong captions until the user clears the cache or uses "Reprocess" for that video. The analysis cache copies the caption file into its own directory, so even though the source is now fixed, old bad copies persist.

Lessons Learned

  • When a system has per-URL cache keying (URL hash), all file outputs should use it — not just thumbnails and analysis data. The subtitle download was an oversight where the temp dir pattern diverged from the caching pattern.
  • find_vtt_file scanning a directory without filtering by video identity is inherently fragile. The real fix is directory isolation (one dir per video), not smarter filename matching.
  • Testing with only a single video will never surface cross-video state contamination bugs. Multi-video test scenarios should be part of the test plan.

Follow-up Items

  • Consider cleaning up the old shared /tmp/video-clipper/subtitles/ directory on app startup
  • Consider adding a migration or auto-invalidation for cached analysis entries that reference caption files from the wrong video