# CLI troubleshooting

> What to do when a tool is missing, a link is blocked, sign-in fails, a key is rejected, minutes run out or a result looks incomplete.

Page: https://scribiz.com/docs/cli/troubleshooting

Start with `scribiz doctor`. It checks your credential, your tools and their versions, and shows the hint for anything missing.

```bash
scribiz doctor
```

Errors print a code, a message and a hint. The code is the same in the CLI, the API and MCP. The exit code tells a script which kind of problem it was.

| Symptom | Code | Exit | Go to |
| --- | --- | --- | --- |
| `zsh: no matches found` with a link | none | 1 | [Quote the link](#quote-the-link) |
| `ffmpeg` or `yt-dlp` not found, or `yt-dlp` does not run | `TOOL_MISSING` | 6 | [A tool is missing](#a-tool-is-missing) |
| `Missing input: one of the arguments is empty` | none | 2 | [An empty argument](#an-empty-argument) |
| A link is refused or returns nothing | `SOURCE_BLOCKED` | 4 | [A link is blocked](#a-link-is-blocked) |
| Instagram says login required | `SOURCE_AUTH_REQUIRED` | 4 | [Instagram and cookies](#instagram-and-cookies) |
| Video private, deleted or not available | `SOURCE_UNAVAILABLE` | 4 | [Not available](#not-available) |
| No audio track | `NO_AUDIO_STREAM` | 4 | [No audio](#no-audio) |
| No credential, or a key rejected | `AUTH` | 3 | [Key problems](#key-problems) |
| `scribiz login` says the code expired or was denied | `AUTH` | 3 | [Sign-in problems](#sign-in-problems) |
| `scribiz login` says `You already have 10 API keys` | `PROVIDER_PROTOCOL` | 5 | [Sign-in problems](#sign-in-problems) |
| Your minutes are used up, or your Gemini key is out of quota | `QUOTA` | 3 | [Out of quota](#out-of-quota) |
| Too many requests | `RATE_LIMIT` | 5 | [Rate limits](#rate-limits) |
| Slow or dropped connection | `NETWORK`, `TIMEOUT`, `SERVER` | 5 | [The service is slow](#the-service-is-slow) |
| Estimate over `--max-cost` | `COST_LIMIT` | 1 | [Over the cost limit](#over-the-cost-limit) |
| Result says some speech may be missing | warning `INCOMPLETE_COVERAGE` | 0 | [Incomplete results](#incomplete-results) |

## Quote the link

A link with `?` or `&` in it needs quotes in zsh, the default shell on a Mac. Without them, zsh reads the `?` as a wildcard and never starts the CLI:

```console
$ scribiz https://www.youtube.com/watch?v=jNQXAC9IVRw
zsh: no matches found: https://www.youtube.com/watch?v=jNQXAC9IVRw
```

Put the link in single quotes, or use the short form of a YouTube link, which has no special characters:

```bash
scribiz 'https://www.youtube.com/watch?v=jNQXAC9IVRw'
scribiz https://youtu.be/jNQXAC9IVRw
```

## An empty argument

An empty argument is a usage error, never the current folder. This happens when a variable in a script is unset: `scribiz "$URL"` with no `$URL`. The message says `Missing input` and the exit code is 2. To run the current folder, write `.` (a dot).

## A tool is missing

`TOOL_MISSING` means `ffmpeg`, `ffprobe` or, for a link that needs it, `yt-dlp` was not found. Install it from [Install the CLI](https://scribiz.com/docs/cli.md#tools-it-needs) and run `scribiz doctor` again. A public YouTube link still works without `yt-dlp`: it is read through Gemini, with approximate timing.

If `scribiz doctor` says `yt-dlp does not run`, it is installed but cannot start, often because it needs a newer Python than the one on your system. `doctor` gives the reason and the command that fixes it. Until then Scribiz treats it as missing.

If you installed the tool and Scribiz still cannot find it, the tool is not on the `PATH` of the process that runs Scribiz. This happens in apps that start the CLI with a bare environment. Scribiz also looks in `/opt/homebrew/bin`, `/usr/local/bin`, `~/.local/bin`, `~/.bun/bin` and `~/.deno/bin`.

## A link is blocked

`SOURCE_BLOCKED` means the site refused the download: an HTTP 403, a bot check, or a request for a token. Try these in order:

1. Update `yt-dlp`. Sites change often, and an old version is the usual cause.
2. Run the same link again. For a public YouTube video Scribiz falls back to the video's captions, and then to having the model read the link, so most YouTube links finish even when downloads are blocked.
3. For other sites, download the file yourself and give Scribiz the file.
4. Use the web tool if you are on a connection the site blocks.

`yt-dlp` needs a JavaScript runtime to read YouTube. If `scribiz doctor` reports none, install Deno, Node or Bun.

## Instagram and cookies

Instagram needs a login for most posts, so a plain link fails with a message like this one:

```console
$ scribiz 'https://www.instagram.com/reel/REEL_ID/'
! Looking up the video failed
✗ Instagram requires login cookies to download media. [Instagram] REEL_ID: Instagram sent an empty media response. ...
  Try one of these:
  1. Log into Instagram in Chrome or Safari, then re-run
  2. scribiz <url> --cookies-from-browser chrome
  3. Export cookies and use: scribiz <url> --cookies cookies.txt
```

Pass the browser you are logged in with:

```bash
scribiz 'https://www.instagram.com/reel/REEL_ID/' --cookies-from-browser chrome
```

- Only that browser is tried. Scribiz never tries them all.
- No browser to read from? Export a cookies file and pass `--cookies path/to/cookies.txt`.
- To skip the flag, put `"cookiesBrowser": "chrome"` in [your config](https://scribiz.com/docs/cli/config.md). It is used for links that need a login, and for nothing else.
- Cookies are read on your machine and are never sent to Scribiz. A hosted request for an Instagram link fails on purpose, with `source_auth_required`, because the server has no login to use.

## Not available

`SOURCE_UNAVAILABLE` means the video is private, deleted or restricted in your region. Open the link in a browser without being signed in to check. `SOURCE_LIVE` means the video is a live stream, which Scribiz does not read. Run it again after the stream ends and the recording is processed.

`SOURCE_TOO_LONG` means the video is over `--max-duration`. See [Sources and limits](https://scribiz.com/docs/sources-and-limits.md#length-limits).

## No audio

A video with no audio track has no speech to transcribe. SRT, VTT and TXT stop with `NO_AUDIO_STREAM`. Ask for what was on screen instead:

```bash
scribiz context ./clip.mov --mode watch
```

`NO_SPEECH_DETECTED` is a warning, not an error. It means the audio has no speech to transcribe, as with music. The Context still holds what was on screen when Watch ran.

## Key problems

`AUTH` (exit 3) means there is no credential, or the one in use was rejected.

```bash
scribiz whoami
```

- No credential at all: run `scribiz login` for a free account, or `scribiz setup` to save your own Gemini key, or set `GEMINI_API_KEY`. In a script, set `SCRIBIZ_API_KEY` or `GEMINI_API_KEY`.
- A Gemini key that Google rejects: check it in [Google AI Studio](https://aistudio.google.com/apikey), and check that the key is not restricted to other APIs. Then run `scribiz setup` again. `GEMINI_API_KEY` in the environment overrides the saved key.
- A Scribiz key that was rejected: it may have been revoked in the dashboard. Run `scribiz login` for a new one, or make one in the [dashboard](https://scribiz.com/dashboard). If `SCRIBIZ_API_KEY` is set, that is the key in use: check it.
- Two credentials set: the one that wins is shown by `whoami`. A `GEMINI_API_KEY` that is still exported wins over a saved sign-in, so signing in does not seem to change anything. Unset it to use your Scribiz minutes. See [Which setting wins](https://scribiz.com/docs/cli/config.md#which-setting-wins).

With `--json`, `--no-input` or without a terminal, Scribiz never prompts. A missing credential is `AUTH` and exit 3.

## Sign-in problems

An expired or denied code stops `scribiz login` with exit code 3. A full set of keys stops it with exit code 5.

- `The sign-in code expired` (exit code 3): a code lasts 10 minutes. Run `scribiz login` again.
- `Sign-in was denied in the browser` (exit code 3): someone pressed Deny on the approval page. Run it again and approve the request.
- `Could not create an API key: You already have 10 API keys` (exit code 5): revoke a key in the [dashboard](https://scribiz.com/dashboard), then run `scribiz login` again.
- The approval page says the code is not complete or already used: type the code as the terminal shows it, or run the command again for a new one.
- No browser on the machine, as on a server or over SSH: use `scribiz login --no-browser` and open the link on another device, or make a key in the dashboard and run `scribiz login --key`.

## Out of quota

With a Scribiz sign-in, `QUOTA` (exit 3) means your minutes are used up. The CLI says so and when they come back:

```text
You are out of minutes for this period.
Your minutes come back on 2026-11-01 (UTC). Your own Gemini key is the other way: run `scribiz setup`.
```

`scribiz whoami` shows the date too. Until then, a run with your own Gemini key works at any time: run `scribiz setup`, or set `GEMINI_API_KEY`. The CLI does not offer a way to add minutes.

With your own Gemini key, `QUOTA` means Google reports that the key is out of quota or rate limited. Check the key's usage and billing in [Google AI Studio](https://aistudio.google.com), or try again later. Google's free tier has its own limits. Scribiz uses no minutes with your own key.

## Rate limits

`RATE_LIMIT` means the service or Google asked Scribiz to slow down. The CLI backs off and retries on its own, a few times with a growing pause, and honors any wait it is told about. If it keeps happening, run fewer jobs at once.

## The service is slow

`NETWORK`, `TIMEOUT` and `SERVER` are retried automatically, a few times with a growing pause. If the run still fails, the same command usually works a minute later. Long audio is already split into pieces, and finished pieces are kept, so a retry does not pay for them again.

## Over the cost limit

`--max-cost` stops a run before it spends anything when the estimate is higher. The error is `COST_LIMIT` and the exit code is 1. Raise the limit, or ask for less: `--mode captions` costs nothing for a video that has captions, and the default SRT output skips the summary.

## Incomplete results

Speech to text can occasionally skip a stretch of speech. Scribiz checks every piece of audio against the places where someone is speaking, and re-runs any piece that has a gap. If a gap is still there, the Context lists it under `coverage.gaps` and carries the warning `INCOMPLETE_COVERAGE`.

- Run again with `--no-cache`. Gaps are often fixed on a second attempt.
- Check `coverage.ratio` in the JSON. A value of 0.9 or more means nearly all detected speech is in the transcript.

## Nothing prints with `--json`

Standard output carries only JSON lines. Human-readable messages go to standard error. Read standard error for the reason, or look for the `error` line. See [The JSON protocol](https://scribiz.com/docs/cli/json-protocol.md).

## Still stuck

Run the command again with the same flags and copy the whole error and its code. With `--json`, include the `runId` from the `start` line. Send it through the [contact form](https://scribiz.com/contact).

---

Checked against the Scribiz build on 2026-10-05.
