zeroclaw-labs/zeroclaw · error · anyhow::Error
runtime.shell {shell:?} (resolved to {}) does not exist
Error message
runtime.shell {shell:?} (resolved to {}) does not exist What it means
After resolution (absolute path taken as-is, bare name found on PATH), validate_shell verifies the resolved target exists. For absolute inputs this is the first real check, so it primarily catches dead absolute paths; for PATH-resolved names it covers the race where the file vanished between lookup and stat.
Source
Thrown at crates/zeroclaw-config/src/platform/mod.rs:61
path.to_path_buf()
} else if path.components().count() > 1 {
anyhow::bail!(
"runtime.shell {shell:?} is a relative path; use a bare name resolved on PATH (e.g. \"bash\") or an absolute path (e.g. \"/bin/bash\")"
);
} else {
match std::env::split_paths(&std::env::var_os("PATH").unwrap_or_default())
.map(|dir| dir.join(shell))
.find(|candidate| candidate.is_file())
{
Some(found) => found,
None => anyhow::bail!(
"runtime.shell {shell:?} was not found on PATH; use an absolute path or install the shell"
),
}
};
if !resolved.exists() {
anyhow::bail!(
"runtime.shell {shell:?} (resolved to {}) does not exist",
resolved.display()
);
}
let metadata = match resolved.metadata() {
Ok(metadata) => metadata,
Err(e) => anyhow::bail!(
"runtime.shell {shell:?} (resolved to {}) could not be inspected: {e}",
resolved.display()
),
};
if !metadata.is_file() {
anyhow::bail!(
"runtime.shell {shell:?} (resolved to {}) is not a regular file",
resolved.display()
);
}View on GitHub (pinned to 88bb9c8533)
Solutions
- Confirm the path exists (ls it), then point at a shell that is actually present.
- Prefer a bare name ("bash") so each machine's PATH picks the right location.
- In the docker runtime, ensure the shell is installed in the container image the config targets.
- Use /bin/sh as the portable floor when targeting heterogeneous machines.
Example fix
# before [runtime] shell = "/usr/bin/fish" # does not exist on this machine # after [runtime] shell = "bash" # resolved per-machine via PATH
Defensive patterns
Strategy: validation
Validate before calling
let resolved = if std::path::Path::new(shell).is_absolute() {
std::path::PathBuf::from(shell)
} else {
resolve_on_path(shell)? // your own PATH walk
};
if !resolved.exists() { /* point at an installed shell before create_runtime */ } Try / catch
match create_runtime(&config) {
Err(e) if e.to_string().contains("does not exist") => {
// verify with ls / file, switch to a bare name or /bin/sh, retry
}
other => other,
} Prevention
- Verify absolute shell paths per machine; prefer bare names for portability.
- For docker runtime, confirm the shell exists in the container image, not just the host.
- Re-check configs after OS upgrades that move or remove shells.
When it happens
Trigger: runtime.shell = "/usr/bin/fish" on a machine without fish; a stale absolute path after the shell was upgraded, moved, or removed; a PATH-found file deleted between resolution and the exists() check.
Common situations: Config copied between machines with different layouts; brew or apt upgrades relocating shells; containers whose runtime image differs from the dev box the config was written on.
Related errors
- runtime.shell must not be empty or whitespace
- runtime.shell {shell:?} is a relative path; use a bare name
- runtime.shell {shell:?} was not found on PATH; use an absolu
- runtime.shell {shell:?} (resolved to {}) could not be inspec
- runtime.shell {shell:?} (resolved to {}) is not a regular fi
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/032b1db3ea8e97d3.
Report an issue: GitHub.