zeroclaw-labs/zeroclaw · error · anyhow::Error
runtime.shell {shell:?} (resolved to {}) could not be inspec
Error message
runtime.shell {shell:?} (resolved to {}) could not be inspected: {e} What it means
validate_shell calls metadata() on the resolved path and surfaces the IO error verbatim when the stat itself fails. Unlike the not-exists case, the path is present but cannot be inspected by this process — EACCES on the file or a parent directory is the classic cause.
Source
Thrown at crates/zeroclaw-config/src/platform/mod.rs:69
.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()
);
}
// 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!(View on GitHub (pinned to 88bb9c8533)
Solutions
- Trace where traversal fails: namei -l /path/to/shell, then chmod a+rx the offending directories.
- Run zeroclaw as a user that can read the path, or move the shell to a system location like /usr/local/bin.
- If the message reports an I/O error rather than permission denied, fix the underlying filesystem or mount problem.
Example fix
# before: stat fails with EACCES on a parent directory $ namei -l /opt/private/sh # shows 'drwx------' on /opt/private # after $ chmod a+rx /opt/private # or move the shell to /usr/local/bin
Defensive patterns
Strategy: try-catch
Validate before calling
if let Err(e) = std::fs::metadata(resolved_shell_path) {
// surface a friendly message: check parent-dir perms (namei -l), user, mount health
return Err(anyhow::anyhow!("cannot inspect shell {path}: {e}"));
} Try / catch
match create_runtime(&config) {
Err(e) if e.to_string().contains("could not be inspected") => {
// inspect errno: PermissionDenied → fix dir perms; other → fix the filesystem/mount
}
other => other,
} Prevention
- Ensure the zeroclaw process user can read and traverse the shell's directory chain.
- Avoid shells under restrictive per-user toolchain dirs for service deployments.
- Use namei -l to diagnose traversal failures quickly.
When it happens
Trigger: The resolved shell path's file or one of its parent directories lacks read/traverse permission for the zeroclaw user, so metadata() returns an error; also races (file deleted mid-check) or filesystem-level failures (NFS stall, I/O error).
Common situations: Running zeroclaw as a service account different from the shell's owner; homebrew or toolchain directories with restrictive permissions; network filesystems; containers with mismatched uid mapping.
Related errors
- runtime.shell {shell:?} (resolved to {}) is not executable
- 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
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/ad1866b53a48ed10.
Report an issue: GitHub.