# What Happens When a Video Lacks Captions and No Whisper API Key Is Provided

> Learn how the watch skill handles videos without captions and a missing Whisper API key. Get a frames-only report and continue visual analysis without errors.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: how-to-guide
- Published: 2026-07-08

---

**When a video lacks captions and no Whisper API key is provided, the `watch` skill outputs a frames-only markdown report containing a clear explanation that transcription is unavailable, allowing visual analysis to continue without raising an error.**

The `claude-video` repository provides a `watch` skill that processes video URLs for AI-powered analysis. When you run this tool on a video without embedded subtitles andhavenot configured a Whisper API key, it gracefully degrades to extracting only visual frames while documenting the missing transcript in the final report.

## How the Watch Skill Handles Missing Transcripts

The transcript acquisition flow follows a strict fallback hierarchy defined in [`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py).

### Attempting Embedded Subtitle Extraction

First, the script attempts to retrieve existing captions via **yt‑dlp**. In [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) around lines 98–104, the code calls `fetch_captions` followed by `parse_vtt` to process any embedded WebVTT subtitles:

```python

# From watch.py - initial caption fetching attempt

subtitle_path = fetch_captions(video_url, working_dir)
if subtitle_path:
    segments = parse_vtt(subtitle_path)

```

If `subtitle_path` is absent or `parse_vtt` raises an exception, the script proceeds to the fallback logic.

### The Three Conditions for Whisper Fallback

The Whisper transcription fallback is guarded by three strict conditions found around lines 389–406 in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py):

1. **`--no-whisper`** is **not** set in the command arguments.
2. A video file was successfully downloaded (`video_path` is truthy).
3. The video metadata confirms an audio stream exists (`meta.get("has_audio")`).

Only if all three conditions evaluate to true will the script attempt to call the Whisper API.

## API Key Detection and Failure Handling

When the caption extraction fails, the tool checks for available API credentials before attempting transcription.

### How load_api_key Validates Credentials

In [`skills/watch/scripts/whisper.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/whisper.py) (lines 65–78), the `load_api_key` function searches for `GROQ_API_KEY` or `OPENAI_API_KEY` in the environment or a local `.env` file. If neither variable is found, the function returns `(None, None)`:

```python

# From whisper.py - credential validation

def load_api_key():
    # Checks for GROQ_API_KEY or OPENAI_API_KEY

    # Returns (None, None) if neither is found

    return (api_key, provider)

```

### Graceful Degradation to Frames-Only Mode

When the API key is missing, the execution reaches an else branch that prints a user-friendly hint to stderr:

```text
[watch] no subtitles and no Whisper API key found — run `python3 <setup.py>` to enable the Whisper fallback

```

The script then continues processing frames. In the final report generation (lines 77–84 in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py)), the "Transcript" section contains a specific explanatory message:

```markdown
_No transcript available — proceed with frames only. Captions were missing and the Whisper fallback was unavailable (no API key set, or `--no-whisper` was used). Run `python3 <setup.py>` to enable Whisper, then re‑run._

```

## Practical Examples and Expected Output

### Running Without an API Key

If you execute the `watch` command on a video without captions and without setting `GROQ_API_KEY` or `OPENAI_API_KEY`, the tool continues with frame extraction:

```bash
watch "https://example.com/video-with-no-captions.mp4" --detail balanced

```

### Generated Report Output

The resulting markdown file contains a frames-only analysis with a documented absence of transcript data:

```markdown
- **Source:** https://example.com/video-with-no-captions.mp4
- **Duration:** 02:15 (135.0s)
- **Detail:** balanced
- **Frames:** 23 selected from 23 candidates (scene engine, full range, budget 23, cap 23)

## Transcript

_No transcript available — proceed with frames only. Captions were missing and the Whisper fallback was unavailable (no API key set, or `--no-whisper` was used). Run `python3 /path/to/skills/watch/scripts/setup.py` to enable Whisper, then re‑run._

```

### Explicitly Disabling Whisper

If you explicitly disable Whisper with the `--no-whisper` flag while captions are also missing, the same explanatory message appears, though the hint may reference the flag rather than the missing key:

```bash
watch "https://example.com/video-with-no-captions.mp4" --detail balanced --no-whisper

```

## Summary

- **Caption-first approach:** The `watch` skill优先考虑 embedded subtitles via `fetch_captions` and `parse_vtt` in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) before attempting any API calls.
- **Conditional fallback:** Whisper transcription only activates if `--no-whisper` is absent, a video file exists, and audio metadata is present.
- **Missing key handling:** The `load_api_key` function in [`whisper.py`](https://github.com/bradautomates/claude-video/blob/main/whisper.py) returns `(None, None)` when neither `GROQ_API_KEY` nor `OPENAI_API_KEY` is configured.
- **Graceful continuation:** Rather than crashing, the tool generates a complete frames-only report with a clear explanation of why the transcript is unavailable.
- **Setup guidance:** The error message and final report both direct users to run [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) to configure API credentials for future runs.

## Frequently Asked Questions

### Will the watch skill fail completely if a video has no captions and I haven't set up Whisper?

No. According to the source code in [`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py), the tool catches the absence of both captions and API keys and continues executing the frame extraction pipeline. It generates a valid markdown report containing only visual analysis with an explanatory note in the Transcript section.

### Can I still perform AI analysis on the video without a transcript?

Yes. The tool proceeds with **frames-only** analysis when transcription is unavailable. The report will contain extracted frame images and their visual descriptions, allowing Claude or other AI systems to analyze the content based solely on visual information.

### How do I enable the Whisper fallback for videos without captions?

Run the setup script mentioned in the error message to configure your API credentials. The script requires either a **Groq** API key (`GROQ_API_KEY`) or an **OpenAI** API key (`OPENAI_API_KEY`), which the `load_api_key` function in [`whisper.py`](https://github.com/bradautomates/claude-video/blob/main/whisper.py) reads from your environment variables or a `.env` file.

### What is the difference between using `--no-whisper` and having no API key?

Both result in a frames-only report, but the causal path differs. Using `--no-whisper` explicitly bypasses the fallback logic in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) (lines 389–406), whereas missing API keys cause the `load_api_key` function to return `(None, None)`, triggering the same degraded path but potentially with different console hints. The final report message covers both scenarios, noting that the fallback was unavailable due to either "no API key set, or `--no-whisper` was used."