From 366374b4ff35e1d314b7b6b5d086dc2f964ea29d Mon Sep 17 00:00:00 2001 From: AaronWander Date: Mon, 2 Mar 2026 14:14:26 +0800 Subject: [PATCH] Sandbox: add actionable error when docker missing (#28547) Co-authored-by: AaronWander --- .../docker.execDockerRaw.enoent.test.ts | 21 +++++++++++++++++++ src/agents/sandbox/docker.ts | 15 +++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/agents/sandbox/docker.execDockerRaw.enoent.test.ts diff --git a/src/agents/sandbox/docker.execDockerRaw.enoent.test.ts b/src/agents/sandbox/docker.execDockerRaw.enoent.test.ts new file mode 100644 index 00000000000..03d287ca172 --- /dev/null +++ b/src/agents/sandbox/docker.execDockerRaw.enoent.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from "vitest"; +import { withEnvAsync } from "../../test-utils/env.js"; +import { execDockerRaw } from "./docker.js"; + +describe("execDockerRaw", () => { + it("wraps docker ENOENT with an actionable configuration error", async () => { + await withEnvAsync({ PATH: "" }, async () => { + let err: unknown; + try { + await execDockerRaw(["version"]); + } catch (caught) { + err = caught; + } + + expect(err).toBeInstanceOf(Error); + expect(err).toMatchObject({ code: "INVALID_CONFIG" }); + expect((err as Error).message).toContain("Sandbox mode requires Docker"); + expect((err as Error).message).toContain("agents.defaults.sandbox.mode=off"); + }); + }); +}); diff --git a/src/agents/sandbox/docker.ts b/src/agents/sandbox/docker.ts index efaa4b0e22e..aac563f2ab9 100644 --- a/src/agents/sandbox/docker.ts +++ b/src/agents/sandbox/docker.ts @@ -65,6 +65,21 @@ export function execDockerRaw( if (signal) { signal.removeEventListener("abort", handleAbort); } + if ( + error && + typeof error === "object" && + "code" in error && + (error as NodeJS.ErrnoException).code === "ENOENT" + ) { + const friendly = Object.assign( + new Error( + 'Sandbox mode requires Docker, but the "docker" command was not found in PATH. Install Docker (and ensure "docker" is available), or set `agents.defaults.sandbox.mode=off` to disable sandboxing.', + ), + { code: "INVALID_CONFIG", cause: error }, + ); + reject(friendly); + return; + } reject(error); });