coleam00/Archon · error

No such image: '${image}'. Build the runner image first: doc

Error message

No such image: '${image}'. Build the runner image first: docker build -t ${image} -f packages/isolation/docker/runner.Dockerfile packages/isolation/docker (${detail})

What it means

dockerPreflight checks that the runner image exists locally. The library never auto-pulls because the image is built from the in-repo Dockerfile, so a missing image is treated as a build step the user skipped, and this error spells out the exact build command.

Source

Thrown at packages/isolation/src/container/docker-exec.ts:111

    // "is Docker running?" (see deployment/docker.md; the socket is root-equivalent).
    const dockerizedHint =
      process.env.ARCHON_DOCKER === 'true'
        ? ' Archon is running inside Docker, which does not mount the Docker daemon socket — ' +
          'the --container backend is unavailable in a dockerized deploy. Run Archon directly ' +
          'on the host, or see deployment/docker.md.'
        : '';
    throw new Error(
      `Cannot connect to the Docker daemon. Is Docker running?${dockerizedHint} (${detail})`
    );
  }

  // 2. Runner image present locally. We never auto-pull — the image is built
  //    from the in-repo Dockerfile, so a miss means "build it", not "pull it".
  try {
    await runner(['image', 'inspect', image], { timeout: 15_000 });
  } catch (err) {
    const detail = extractDockerError(err);
    throw new Error(
      `No such image: '${image}'. Build the runner image first: ` +
        `docker build -t ${image} -f packages/isolation/docker/runner.Dockerfile packages/isolation/docker (${detail})`
    );
  }
}

/**
 * Pull the best available error text off a rejected `execFile` promise: the
 * child's stderr if present, else the error message. Used to enrich preflight
 * errors and to feed `classifyIsolationError`.
 */
export function extractDockerError(err: unknown): string {
  const e = err as Error & { stderr?: string; stdout?: string };
  const stderr = (e.stderr ?? '').trim();
  if (stderr) return stderr.split('\n')[0] ?? stderr;
  return (e.message ?? String(err)).split('\n')[0] ?? String(err);
}

View on GitHub (pinned to 0773b97458)

Solutions

  1. Build the runner image: docker build -t <image> -f packages/isolation/docker/runner.Dockerfile packages/isolation/docker
  2. Re-run the repo setup script if one exists (check package.json)
  3. If a version bump renamed the tag, rebuild/pull the new tagged image

Example fix

// before
archon --container ...   # fails: image not built
// after
docker build -t archon-runner -f packages/isolation/docker/runner.Dockerfile packages/isolation/docker
archon --container ...
Defensive patterns

Strategy: validation

Validate before calling

import { execFile } from 'child_process';
function imageExists(image: string): Promise<boolean> {
  return new Promise(res => execFile('docker', ['image', 'inspect', image], err => res(!err)));
}
if (!(await imageExists('archon-runner'))) {
  console.error('Build it: docker build -t archon-runner -f packages/isolation/docker/runner.Dockerfile packages/isolation/docker');
}

Try / catch

try {
  await backend.prepare(opts);
} catch (err) {
  if (String(err).startsWith("No such image: '")) {
    // build the runner image per the message, then retry once
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling prepare()/p() with the container backend before ever building the runner image, or after pruning images (`docker image prune -a`).

Common situations: Fresh clone where the setup step was skipped; image removed by disk cleanup; image tag changed by a version bump so the old tag no longer exists.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/d5e6a00fcef809a8. Report an issue: GitHub.