---
title: Sandbox providers
description: >-
  The contract a sandbox provider meets before any attempt starts, and what
  reeval does with its failures.
---
> ## 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.

A sandbox provider is what makes and starts a sandbox: Docker today (and Podman, through the same provider), with the fake sandbox as a second. Before any attempt starts, reeval asks each provider in the plan to check it can work, then to prepare every distinct sandbox the attempts need. The provider classes each failure; reeval does the rest the same way for every provider.

```ts
interface SandboxProvider {
  kind: string
  // credentials, connectivity
  check(): Promise<void>
  // attempts with one key share one sandbox
  key(sandbox, harness): string
  // build, pull or provision
  prepare(sandbox, harness, ctx): Promise<Handle>
  // config, transient or resource
  classify(error): PrepareFailure
}
```

## What a provider does

| Step | Provider | Docker |
|---|---|---|
| `check` | Checks its credentials and connection once per run | Docker is running |
| `key` | Names what a sandbox's content depends on | The harness and `image`, `from`, `dockerfile`, `install` |
| `prepare` | Makes the sandbox, wrapping each network step in `ctx.retry`, and returns what attempts start from | Builds or finds the image, returns its ref and id |
| `classify` | Classes a failure and names its stage | `image`, `from`, `dockerfile`, `harness` or `install` |

## Failure classes

| Class | Means | reeval |
|---|---|---|
| `config` | The setup is wrong: a bad token, a failing build step, a missing image | Fails at once, never retried |
| `transient` | The network, a registry or API 5xx, a quota | Retried twice, after 2 s and 8 s |
| `resource` | Out of memory (`oom`) or disk (`enospc`) | Named in the headline, not retried |

A failed `check` stops the run: exit 2 when it's the setup (a bad token, Docker not running), else 3.

## What reeval does with them

| Where the sandbox is set | When it can't be prepared |
|---|---|
| The config or a profile's defaults (and the harness too) | The run stops before any attempt: exit 3, or 2 when the fix is in the config |
| A group or an eval | Only the attempts that need it fail, once each, as infra errors; the rest run |

Each distinct sandbox is prepared once per run, three at a time, and a failure is kept for the run: no other attempt prepares it again. The terminal, one GitHub Actions annotation per sandbox, `summary.md` and each attempt's `error.prepare` in the [record](/reference/record) carry the failure's headline, stage, class, cause, log and the levels that set it.

`test/sandbox-prepare-contract.test.ts` holds every provider to this, with a scripted provider that fails in each class (including a bad API token) beside Docker.

## Related

- [docker()](/reference/sandbox/docker)
- [fakeSandbox()](/reference/sandbox/fake)
- [Sandboxes guide](/guide/sandboxes#when-an-image-fails)
