Hmbown/CodeWhale · error · SpawnError

docker_unavailable

docker_unavailable

Error message

A Linux Docker engine is required — start Docker Desktop in Linux-container mode (or Colima) and spawn again

What it means

Thrown by spawnDockerComputer() before doing any work when dockerAvailable() reports there is no usable Linux Docker engine. The plugin requires a Linux-container engine (it checks `docker info --format {{.OSType}}` returns "linux" within 10s); Docker Desktop in Windows-container mode or a non-Linux engine is rejected up front with this actionable message.

Solutions

  1. Start Docker Desktop (in Linux-container mode) or run `colima start`, then spawn again.
  2. On Docker Desktop for Windows, switch to Linux containers via the tray icon ('Switch to Linux containers...').
  3. Verify with `docker info --format '{{.OSType}}'` — it must print `linux`.
  4. If docker is not installed, install Docker Engine/Colima first.

Example fix

// before (Windows)
$ docker info --format '{{.OSType}}'
windows
// after
// Docker Desktop tray -> 'Switch to Linux containers...', then:
$ docker info --format '{{.OSType}}'
linux
Defensive patterns

Strategy: validation

Validate before calling

import { execFile } from "node:child_process";
import { promisify } from "node:util";
const pexec = promisify(execFile);
async function linuxDockerReady() {
  try {
    const { stdout } = await pexec("docker", ["info", "--format", "{{.OSType}}"], { timeout: 10_000 });
    return stdout.trim() === "linux";
  } catch { return false; }
}

Try / catch

try {
  await spawnDockerComputer();
} catch (e) {
  if (e?.code === "docker_unavailable") {
    // show the message's actionable guidance: start Docker Desktop in Linux mode or Colima
  }
}

Prevention

When it happens

Trigger: spawnDockerComputer() called while: docker CLI missing, daemon stopped, Docker Desktop set to Windows containers (OSType != "linux"), or the `docker info` probe times out.

Common situations: Docker Desktop not started after reboot, Windows containers mode active, Colima VM not running on macOS, DOCKER_HOST pointing at a dead remote, or docker not installed in a container/CI image.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/18a7ad768ae6b104. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/plugins/computer-use/src/spawn.mjs:77

  const inspect = await docker(["image", "inspect", image], { timeoutMs: 15_000 });
  if (inspect.code === 0) return { built: false };
  if (image !== DEFAULT_IMAGE) {
    throw new SpawnError("spawn_image_missing", `docker image "${image}" is not present locally`);
  }
  const r = await docker(["build", "-t", image, "-f", path.join(PLUGIN_ROOT, "docker", "Dockerfile"), PLUGIN_ROOT], { timeoutMs: 15 * 60_000 });
  if (r.aborted) throw Object.assign(new ExecError("computer request cancelled", r), { code: "cancelled" });
  if (r.code !== 0) throw new SpawnError("spawn_failed", `docker build ${image} failed: ${trim(r.stderr || r.stdout, 800)}`, r);
  return { built: true };
}

/**
 * Start a disposable desktop container and verify the agent answers inside
 * its session. On any failure the container is removed — spawn is
 * transactional: either a live computer comes back or nothing was left.
 */
export async function spawnDockerComputer({ id, image = DEFAULT_IMAGE } = {}) {
  if (!await dockerAvailable()) {
    throw new SpawnError("docker_unavailable", "A Linux Docker engine is required — start Docker Desktop in Linux-container mode (or Colima) and spawn again");
  }
  const { built } = await ensureImage(image);
  const container = `cu-spawn-${id}-${crypto.randomBytes(3).toString("hex")}`;
  const cleanup = async () => {
    await docker(["rm", "-f", container], { timeoutMs: 15_000, signal: null }).catch(() => {});
  };
  try {
    // --init reaps the desktop's children; --ipc=host keeps Chromium off the
    // 64MB default /dev/shm, same as docker/run.sh. "sleep infinity" is the
    // payload — the image entrypoint stands up Xvfb/openbox/the session bus
    // first, and the agent is exec'd in per request.
    await dockerOk([
      "run", "-d", "--name", container,
      "--init", "--ipc=host",
      "--label", `${SPAWN_LABEL}=1`,
      "--label", `${SESSION_LABEL}=${SESSION_ID}`,
      "--label", `${COMPUTER_LABEL}=${id}`,
      image, "sleep", "infinity",

View on GitHub (pinned to 73e0f67d83)