{"record":{"id":"ad1866b53a48ed10","repo":"zeroclaw-labs/zeroclaw","slug":"runtime-shell-shell-resolved-to-could-not","errorCode":null,"errorMessage":"runtime.shell {shell:?} (resolved to {}) could not be inspected: {e}","messagePattern":"runtime\\.shell (.+?) \\(resolved to (.+?)\\) could not be inspected: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/platform/mod.rs","lineNumber":69,"sourceCode":"            .find(|candidate| candidate.is_file())\n        {\n            Some(found) => found,\n            None => anyhow::bail!(\n                \"runtime.shell {shell:?} was not found on PATH; use an absolute path or install the shell\"\n            ),\n        }\n    };\n\n    if !resolved.exists() {\n        anyhow::bail!(\n            \"runtime.shell {shell:?} (resolved to {}) does not exist\",\n            resolved.display()\n        );\n    }\n\n    let metadata = match resolved.metadata() {\n        Ok(metadata) => metadata,\n        Err(e) => anyhow::bail!(\n            \"runtime.shell {shell:?} (resolved to {}) could not be inspected: {e}\",\n            resolved.display()\n        ),\n    };\n    if !metadata.is_file() {\n        anyhow::bail!(\n            \"runtime.shell {shell:?} (resolved to {}) is not a regular file\",\n            resolved.display()\n        );\n    }\n\n    // Coarse check: reject only when no execute bit is set at all. A precise\n    // \"can *we* execute it\" test (uid/gid vs. the file owner) buys little —\n    // the kernel's spawn is the real authority (ACLs, caps, mount flags) — and\n    // this is a fail-fast sanity check, not a security gate.\n    let mode = metadata.permissions().mode();\n    if mode & 0o111 == 0 {\n        anyhow::bail!(","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/platform/mod.rs#L51-L87","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"# before: stat fails with EACCES on a parent directory\n$ namei -l /opt/private/sh   # shows 'drwx------' on /opt/private\n\n# after\n$ chmod a+rx /opt/private    # or move the shell to /usr/local/bin","handlingStrategy":"try-catch","validationCode":"if let Err(e) = std::fs::metadata(resolved_shell_path) {\n    // surface a friendly message: check parent-dir perms (namei -l), user, mount health\n    return Err(anyhow::anyhow!(\"cannot inspect shell {path}: {e}\"));\n}","typeGuard":null,"tryCatchPattern":"match create_runtime(&config) {\n    Err(e) if e.to_string().contains(\"could not be inspected\") => {\n        // inspect errno: PermissionDenied → fix dir perms; other → fix the filesystem/mount\n    }\n    other => other,\n}","preventionTips":["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."],"tags":["runtime","shell","permissions","io"],"backgroundTag":"file-permission-denied","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}