zeroclaw-labs/zeroclaw · error · anyhow::Error
runtime.shell {shell:?} (resolved to {}) is not a regular fi
Error message
runtime.shell {shell:?} (resolved to {}) is not a regular file What it means
validate_shell requires the resolved shell path to be a regular file. Directories, fifos, sockets, and device nodes all parse as paths but cannot be exec'd as a program, so they are rejected before spawn.
Source
Thrown at crates/zeroclaw-config/src/platform/mod.rs:75
}
};
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()
);
}
// Coarse check: reject only when no execute bit is set at all. A precise
// "can *we* execute it" test (uid/gid vs. the file owner) buys little —
// the kernel's spawn is the real authority (ACLs, caps, mount flags) — and
// this is a fail-fast sanity check, not a security gate.
let mode = metadata.permissions().mode();
if mode & 0o111 == 0 {
anyhow::bail!(
"runtime.shell {shell:?} (resolved to {}) is not executable",
resolved.display()
);
}
Ok(())View on GitHub (pinned to 88bb9c8533)
Solutions
- Point at the shell binary itself, not its directory.
- Inspect what the path really is: ls -l and file <path>; fix or remove symlinks that target a non-file.
- If the shell package's files are corrupted, reinstall it.
Example fix
# before [runtime] shell = "/usr/bin" # a directory # after [runtime] shell = "/usr/bin/bash"
Defensive patterns
Strategy: type-guard
Validate before calling
if !is_regular_file(&resolved_shell_path) {
return Err(anyhow::anyhow!("shell path is not a regular file"));
} Type guard
fn is_regular_file(p: &std::path::Path) -> bool {
std::fs::metadata(p).map(|m| m.is_file()).unwrap_or(false)
} Try / catch
match create_runtime(&config) {
Err(e) if e.to_string().contains("not a regular file") => {
// path points at a dir/fifo/socket; point at the binary itself
}
other => other,
} Prevention
- Point at the shell binary, never its directory.
- Check ls -l / file on unusual paths (tool-managed symlinks) before configuring them.
- Lint configs for shell values ending in a path separator.
When it happens
Trigger: runtime.shell resolving to a directory ("/usr/bin" instead of "/usr/bin/bash"), a symlink whose target is a fifo or socket, or a device node.
Common situations: Typos dropping the binary name and leaving the trailing slash or bare directory; tool-managed symlinks that replaced the binary with something odd; minimal container images with an unusual /bin.
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 {}) does not exist
- runtime.shell {shell:?} (resolved to {}) could not be inspec
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/3853685573433ab9.
Report an issue: GitHub.