{"record":{"id":"51fd15b6a25e7f8e","repo":"Hmbown/CodeWhale","slug":"no-executable-search-path-is-configured","errorCode":null,"errorMessage":"no executable search path is configured","messagePattern":"no executable search path is configured","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/shell.rs","lineNumber":3883,"sourceCode":"    let workspace = workspace.canonicalize().ok()?;\n    let safe = std::env::split_paths(path).filter_map(|entry| {\n        if !entry.is_absolute() {\n            return None;\n        }\n        let resolved = entry.canonicalize().ok()?;\n        (!resolved.starts_with(&workspace)).then_some(resolved)\n    });\n    std::env::join_paths(safe).ok()\n}\n\nfn readonly_sanitized_path(workspace: &std::path::Path) -> Option<String> {\n    let path = std::env::var_os(\"PATH\")?;\n    readonly_sanitized_path_from(workspace, &path).map(|value| value.to_string_lossy().into_owned())\n}\n\nfn resolve_readonly_program(program: &str, workspace: &std::path::Path) -> Result<PathBuf> {\n    let path = std::env::var_os(\"PATH\")\n        .ok_or_else(|| anyhow!(\"no executable search path is configured\"))?;\n    resolve_readonly_program_from_path(program, workspace, &path)\n}\n\nfn resolve_readonly_program_from_path(\n    program: &str,\n    workspace: &std::path::Path,\n    path: &std::ffi::OsStr,\n) -> Result<PathBuf> {\n    let workspace = workspace.canonicalize()?;\n    if std::path::Path::new(program).components().count() != 1 {\n        return Err(anyhow!(\n            \"read-only command must name a bare allowlisted executable\"\n        ));\n    }\n    let safe_path = readonly_sanitized_path_from(&workspace, path).ok_or_else(|| {\n        anyhow!(\"no trusted executable search path remains outside the workspace\")\n    })?;\n    let names = if cfg!(windows) {","sourceCodeStart":3865,"sourceCodeEnd":3901,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tools/shell.rs#L3865-L3901","documentation":"The read-only executor resolves the program binary itself against PATH so workspace entries can be excluded from the search; if `std::env::var_os(\"PATH\")` returns None the resolution cannot even start and this error is returned. The Codewhale process was launched with no PATH at all, so every read-only command will fail the same way until the environment is fixed.","triggerScenarios":"Running the TUI/headless exec host under an environment with PATH unset: `env -i`, minimal systemd units without `Environment=PATH=...`, container configs that define PATH only for login shells, or tests that clear the environment before dispatching a read-only command.","commonSituations":"Launching from wrappers or service managers that sanitize the environment; CI jobs with scrubbed env; debugging sessions started with a stripped env.","solutions":["Set PATH to include standard system bin dirs (/usr/bin:/bin:/usr/local/bin) before starting the TUI","For systemd services, add an explicit `Environment=PATH=...` directive to the unit","Fail fast at startup with a clear configuration error instead of discovering it at the first read-only command","For tests, re-inject a minimal PATH before exercising the readonly path"],"exampleFix":"# before: launched with a scrubbed environment\nenv -i codewhale tui\n# after: keep a sane PATH\nenv -i PATH=/usr/bin:/bin codewhale tui","handlingStrategy":"validation","validationCode":"let Some(path) = std::env::var_os(\"PATH\") else {\n    return Err(anyhow!(\"PATH is unset; set it before starting Codewhale\"));\n};\nif std::env::split_paths(&path).next().is_none() {\n    return Err(anyhow!(\"PATH is empty\"));\n}","typeGuard":"fn path_configured() -> bool {\n    std::env::var_os(\"PATH\").is_some_and(|p| std::env::split_paths(&p).next().is_some())\n}","tryCatchPattern":"if let Err(err) = run_readonly_command(&command) {\n    if err.to_string().contains(\"no executable search path is configured\") {\n        return Err(anyhow!(\"environment misconfigured: PATH is unset; restart with a sane PATH\"));\n    }\n    return Err(err);\n}","preventionTips":["Assert PATH is set at process startup, before any tool dispatch","For systemd units, set `Environment=PATH=/usr/bin:/bin` explicitly","Avoid `env -i` launches unless you re-inject PATH","Test environments must re-establish PATH before exercising read-only execution"],"tags":["readonly-shell","environment","path","configuration","rust"],"backgroundTag":"missing-path-env-var","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}