JuliusBrussee/caveman · error · Error
caveman-code: host command shell is not available
Error message
caveman-code: host command shell is not available
What it means
The bash tool spawns the host shell produced by `hostShellInvocation` (platform-dependent /bin/bash or sh). If that shell binary cannot be spawned at all (ENOENT/EPERM), the run is marked spawnFailed and this error is thrown. It is an environment capability failure, not a failure of the command itself.
Source
Thrown at packages/agent/src/code.ts:316
`Times out after ${BASH_TIMEOUT_MS} ms; output is capped at ${caps.bash} bytes.`,
input: schema.object({
command: schema.string(),
timeoutMs: schema.optional(schema.integer()),
}),
effect: "external",
result: "inline",
timeoutMs: BASH_TIMEOUT_MS,
async execute(input, signal) {
const timeoutMs = Math.min(input.timeoutMs ?? BASH_TIMEOUT_MS, BASH_TIMEOUT_MS);
const shell = hostShellInvocation(input.command, process.platform, buildCodingProcessEnv());
const run = await runProcess(
shell.command,
shell.args,
await workspaceRoot(),
timeoutMs,
signal,
);
if (run.spawnFailed) throw new Error("caveman-code: host command shell is not available");
const body = [
`exit ${run.timedOut ? `timeout after ${timeoutMs}ms` : run.code}`,
run.output.trim() === "" ? "(no output)" : run.output,
].join("\n");
const text = capOutput(body, caps.bash);
record(`bash:${input.command.slice(0, 60)}`, text);
return text;
},
});
const editTool = tool({
name: "edit_file",
description:
"Replace an exact string in a workspace file. The old string must appear exactly " +
"once unless replace_all is set. Writes to disk.",
input: schema.object({
path: schema.string(),
old_string: schema.string(),View on GitHub (pinned to 27d5a3981a)
Solutions
- Ensure a POSIX shell (bash or sh) exists and is executable in the agent's runtime environment; on Windows install Git Bash or WSL and make it reachable
- Check that the process env passed to the agent does not clobber PATH — buildCodingProcessEnv may sanitize it, so keep the shell's directory on the sanitized PATH
- If the host genuinely has no shell, route work to the other tools (edit_file, grep) instead of bash, or run the agent in a proper container
- Verify spawn capability directly: `node -e "require('child_process').spawnSync(process.platform==='win32'?'bash':'/bin/sh',['-c','echo ok'])"` in the same environment
Example fix
// before: PATH sanitized to empty, shell unresolvable
env: { PATH: "" }
// after: keep system dirs on PATH so hostShellInvocation can spawn
env: { PATH: "/usr/local/bin:/usr/bin:/bin" } Defensive patterns
Strategy: validation
Validate before calling
import { spawnSync } from "node:child_process";
function shellAvailable(): boolean {
const shell = process.platform === "win32" ? "bash" : "/bin/sh";
return spawnSync(shell, ["-c", "true"]).error === undefined;
}
if (!shellAvailable()) throw new Error("no host shell; bash tool disabled"); Try / catch
try {
const res = await bashTool.execute({ command }, signal);
} catch (err) {
if (err instanceof Error && err.message.includes("host command shell is not available")) {
// do not retry the command; fix the environment instead
throw new Error(`shell missing on host (${process.platform}); install bash/sh`);
}
throw err;
} Prevention
- On Windows, install Git Bash or run under WSL and verify bash resolves on PATH
- Keep /bin and /usr/bin on the PATH your process env builder produces
- Prefer the dedicated read/edit/grep tools for file work so a missing shell degrades gracefully
When it happens
Trigger: Invoking the `bash` tool on a host without a usable shell binary: Windows without bash (only cmd/powershell exist), containers with no shell, or environments where buildCodingProcessEnv() strips PATH entries containing the shell, or execute permissions deny spawning it.
Common situations: Windows deployments (no /bin/bash); minimal/distroless containers; macOS sandbox-exec profiles blocking /bin/sh; a PATH env var overwritten to a directory set that excludes /bin and /usr/bin.
Related errors
- caveman-code: neither rg nor grep is available
- cave_harness_aborted
- cave_vercel_terminal_failure
- probe returned false
- empty version output
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/37c40253d61d80ed.
Report an issue: GitHub.