---
title: reeval doctor
description: Check that a project is ready to run, with a fix for every problem.
---
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reeval.ai/llms.txt
> Use this file to discover all available pages before exploring further.

`reeval doctor` checks what `reeval run` needs, without running anything, and prints the fix for each problem. It exits 0 when nothing failed and 1 when something did.

```bash
npx reeval doctor
npx reeval doctor --online --json
```

## Flags

[//]: # (generated:cli-help:doctor)

```text
reeval doctor                 Check Node and npm, the config, Docker and its memory, the sandbox
                              images, the keys of each harness, the judge and analysis.model,
                              egress, .gitignore and keys in .env files git sees; exit 1 on a
                              problem, each with its fix. Never prints a key
  --online                    Also try each key with one tiny authenticated request
  --json                      The checks as JSON
```

[//]: # (/generated:cli-help:doctor)

## Output

A real run in a project from `reeval init --yes`, with its image built but no key set:

```text
reeval doctor · reeval.config.ts
✓ runtime    node 22.23.3 (reeval needs Node >=22.13)
✓ config     reeval.config.ts: harness cursor:composer-2.5, sandbox docker, profiles pr, nightly
✓ docker     running · 4 CPUs, 15.6 GB memory (default concurrency 4)
✓ image      reeval-sandbox:cursor-0.1.6 (cursor)
✗ key        CURSOR_API_KEY for cursor:composer-2.5: not set
             fix: add CURSOR_API_KEY=... to .env.local
! analysis   GOOGLE_GENERATIVE_AI_API_KEY (for direct()) for google/gemini-3.8-flash (analysis.model): not set
             fix: add GOOGLE_GENERATIVE_AI_API_KEY=... to .env.local
✓ egress     proxy: the agents reach any host over HTTP(S) through the egress gateway, which records it; nothing else leaves the sandbox (the default); evals and environments may set their own
✓ gitignore  .env* and .reeval/ are ignored

1 problem, 1 warning. Fix it and run reeval doctor again.
```

`✓` passed, `!` is a warning (exit 0), `✗` is a problem (exit 1), and `-` was skipped. A config with no judge model shows no `judge` line unless an eval file, or a module it imports by a relative path, calls `c.judge`. A config without `analysis.model` gets a warning instead of a key check, unless `analysis.insights` is `false`:

```text
! analysis   no analysis.model, so runs print no insights
             fix: set analysis: { model: 'google/gemini-3.8-flash' } in reeval.config.ts for answers to what each eval asks, or analysis: { insights: false } to go without
```

A model's line names the key its gateway takes: its provider's own without a `gateway` list. With only `AI_GATEWAY_API_KEY` set, the fix says how to use it:

```text
✗ judge      TYPESAFE_AI_API_KEY (for direct()) for typesafe-ai/jev-1.14.0: not set
             fix: add TYPESAFE_AI_API_KEY=... to .env.local, or add vercel() to gateway to use the AI_GATEWAY_API_KEY that's set
```

## Checks

| Check | Problem (`✗`) | Warning (`!`) |
|---|---|---|
| `runtime` | Node, or the Node version Bun or Deno provides, is older than the package's `engines` | |
| `config` | No `reeval.config.*` here or above, or it doesn't load | |
| `evals` | | The eval files didn't load, so the `image` and `key` checks use the config's own harnesses (`reeval run --dry-run` shows why). Shown only then |
| `docker` | Not installed (no `docker` command), not running, or running Windows containers, when a sandbox in the config or a profile is `docker()` | Under 4 GB of memory, one attempt's default limit |
| `image` | reeval's sandbox image for a planned harness isn't built, a `docker({ image })` isn't in Docker, or Docker couldn't say whether an image is there (`couldn't be checked: …`, with Docker's error) | Images for this harness from another reeval version |
| `key` | A planned harness's key isn't set, has whitespace in it, or (`--online`) its API rejects it | A key only another profile's harness needs isn't set; `--online` couldn't reach the API |
| `judge` | None of the keys that work for the judge model's prefix is set, or the one reeval would send has whitespace in it | The same, for a profile's judge; or no judge model is set and an eval file calls `c.judge` |
| `analysis` | `analysis.model`'s key has whitespace in it | `analysis.model` isn't set (and `analysis.insights` isn't `false`), or none of the keys that work for its prefix is set: the run's [insights](/concepts/insights) need both |
| `gateway` | A harness in the config or a profile that no entry of its [`gateway` list](/reference/gateway) can serve, or an expired `VERCEL_OIDC_TOKEN` under `vercel()`. Otherwise it shows where each harness resolves. Shown only when the config or a profile sets `gateway` | |
| `egress` | A sandbox can't enforce its policy, such as a restricted policy on `fakeSandbox()` | The config or a profile sets `'allow-all'` on a CI runner (`GITHUB_ACTIONS`, `GITLAB_CI`, `BUILDKITE`, `CIRCLECI`, `CI`), a cloud VM (its firmware's vendor in `/sys/class/dmi/id`) or a machine whose cloud metadata service (`169.254.169.254`) answers: the sandbox can reach it around the gateway |
| `gitignore` | `.env*` isn't ignored | `.reeval/` isn't ignored |
| `env-files` | | A `.env` or `.env.*` file git doesn't ignore, such as `.env.example`, sets a `*KEY*`, `*TOKEN*`, `*SECRET*`, `*PASSWORD*` or `*CREDENTIAL*` variable to a value that isn't empty or a placeholder (`<key>`, `your-key-here`, `${KEY}`, `xxx`). Shown only when git sees such a file |

## Docker on each platform

reeval's sandboxes are Linux containers. The `docker` check's fix names what your platform needs:

| Platform | Docker isn't running | Docker runs Windows containers |
|---|---|---|
| Linux | `start Docker Desktop, or the Docker service (sudo systemctl start docker)` | |
| macOS | `start Docker Desktop (or another Docker engine, such as OrbStack or Colima)` | |
| Windows | `install or start Docker Desktop with the WSL 2 backend and Linux containers (…)` | `switch Docker Desktop to Linux containers (its tray menu: Switch to Linux containers), on the WSL 2 backend` |

Keys come from the environment and the `.env.local` and `.env` beside the config, as `reeval run` reads them. `reeval doctor` names each key but never prints its value, in text or JSON.

The `image` and `key` checks cover the harnesses a run would use: doctor collects the evals as `reeval run --dry-run` does, under the profile a run would pick, and checks each planned attempt's harness and sandbox, so the images are the ones `reeval image build` would build. A harness only reeval's default names (`harness cursor:composer-2.5 (reeval's default)` on the `config` line) gets no image or key check unless an eval runs it. When images are missing and `reeval doctor` runs in a terminal, it offers to build them with `reeval image build`.

## --online

```text
✗ key        CURSOR_API_KEY for cursor:composer-2.5: set, but api.cursor.com rejects it (HTTP 401)
             fix: set a valid CURSOR_API_KEY in .env.local
```

With `--online`, each key goes in one request to its API, only in a header: `GET /v0/me` on `api.cursor.com`, `GET /v1/models` on `api.anthropic.com`, `GET /v1beta/models` on `generativelanguage.googleapis.com` and `GET /v1/models` on `api.openai.com`. HTTP 401 or 403 is a problem. Other keys, such as `TYPESAFE_AI_API_KEY`, are only checked for being set.

## --json

```json
{
  "healthy": false,
  "problems": 1,
  "warnings": 1,
  "config": "reeval.config.ts",
  "checks": [
    {
      "id": "runtime",
      "status": "ok",
      "summary": "node 22.23.3 (reeval needs Node >=22.13)"
    },
    …
  ]
}
```

`status` is `ok`, `warn`, `fail` or `skip`; a check with a fix has `fix`.

## Related

- [reeval init](/reference/cli/init): scaffolds a project that passes these checks, once Docker runs and the key is set
- [Your first real run](/guide/first-real-run): Docker, the image and keys
