Hmbown/CodeWhale · error · SpawnError
spawn_failed
spawn_failed
Error message
docker ${args[0]} timed out What it means
Thrown by dockerOk() when a docker CLI invocation exceeds its per-command timeout. dockerOk wraps all docker calls used to validate/read the Docker engine state, and any command that neither aborted nor exited but hit its time budget produces this error instead of hanging forever. The message names the docker subcommand that timed out.
Solutions
- Check `docker info` in a terminal; if it hangs, restart the Docker daemon / Docker Desktop.
- Retry the operation once the engine responds — this is usually transient daemon latency.
- If on Colima or a remote DOCKER_HOST, verify the engine is running and reachable (`colima status`, `docker context ls`).
- If the command legitimately needs longer, pass a larger timeoutMs in opts to the plugin's docker calls.
Example fix
// before
dockerOk(["image", "inspect", image]); // default timeout, stalls on slow daemon
// after
await dockerOk(["image", "inspect", image], { timeoutMs: 30_000 }); Defensive patterns
Strategy: retry
Validate before calling
// preflight probe
const ok = await dockerAvailable(); // runs docker info with a 10s budget
if (!ok) throw new Error("docker engine not responding"); Try / catch
try {
await spawnDockerComputer();
} catch (e) {
if (e?.code === "spawn_failed" && /timed out/.test(e.message)) {
// wait, confirm `docker info` responds, then retry once
}
} Prevention
- Ensure the Docker daemon is running and warm before spawning.
- Keep a preflight `docker info` health check in your startup path.
- Pass generous timeoutMs for commands on slow or remote engines.
- Avoid spawning while the host is under heavy I/O load.
When it happens
Trigger: Any dockerOk() call (e.g. dockerAvailable's 'docker info' with timeoutMs: 10_000, or 'image inspect' with 15s) where the spawned docker process runs past its timeoutMs and sets r.timedOut.
Common situations: Docker Desktop is starting up or wedged, the docker daemon is unresponsive under heavy load, disk I/O saturation slows the CLI, or a network-attached engine (Colima, remote DOCKER_HOST) is unreachable and the CLI stalls instead of failing fast.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- docker exec : timed out
- DS4 /v1/models timed out after 15 seconds at
- GET timeout
- Request timeout after 15 seconds
- SSE stream idle timeout after
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/3f89f5faecc64e18.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/spawn.mjs:43
class SpawnError extends ExecError {
constructor(code, message, result) {
super(message, result);
this.code = code;
}
}
function docker(args, opts = {}) {
// Docker CLI lives off PATH; on macOS a Colima/Docker-Desktop install puts
// it in /usr/local/bin or /opt/homebrew/bin which the MCP host's PATH may
// lack, so try the well-known paths too.
return run("docker", args, opts);
}
async function dockerOk(args, opts = {}) {
const r = await docker(args, opts);
if (r.aborted) throw Object.assign(new ExecError("computer request cancelled", r), { code: "cancelled" });
if (r.timedOut) throw new SpawnError("spawn_failed", `docker ${args[0]} timed out`, r);
if (r.code !== 0) throw new SpawnError("spawn_failed", `docker ${args[0]} failed: ${trim(r.stderr || r.stdout)}`, r);
return r;
}
export async function dockerAvailable(command = docker) {
const r = await command(["info", "--format", "{{.OSType}}"], { timeoutMs: 10_000 });
return r.code === 0 && !r.timedOut && !r.aborted && r.stdout.trim() === "linux";
}
/**
* The image must exist locally. The plugin's own image is built from
* docker/Dockerfile on first use; any other image name is the caller's
* responsibility — we never guess a build context for it.
*/
async function ensureImage(image) {
const inspect = await docker(["image", "inspect", image], { timeoutMs: 15_000 });
if (inspect.code === 0) return { built: false };
if (image !== DEFAULT_IMAGE) {View on GitHub (pinned to 73e0f67d83)