{"record":{"id":"f02380d563e1a8ff","repo":"Hmbown/CodeWhale","slug":"read-only-executable-path-is-not-valid-utf-8","errorCode":null,"errorMessage":"read-only executable path is not valid UTF-8","messagePattern":"read-only executable path is not valid UTF-8","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/shell.rs","lineNumber":2013,"sourceCode":"        let policy = policy_override.unwrap_or_else(|| self.sandbox_policy.clone());\n\n        // Create command spec and prepare sandboxed environment\n        let spec = if let Some(workspace) = readonly_workspace {\n            if command.contains('|') {\n                // An agent read-only pipeline: every segment was admitted by\n                // `is_agent_readonly_shell_command` (no separators, redirects,\n                // expansions, or subshells — only `|` between validated\n                // segments), so a shell is needed solely to bind the segments\n                // and report a failed stage through pipefail.\n                let piped = format!(\"set -o pipefail; {command}\");\n                CommandSpec::shell(&piped, work_dir.clone(), Duration::from_millis(timeout_ms))\n            } else {\n                let (program, args) = hardened_readonly_argv(command)?;\n                let program = resolve_readonly_program(&program, workspace)?;\n                CommandSpec::program(\n                    program\n                        .to_str()\n                        .ok_or_else(|| anyhow!(\"read-only executable path is not valid UTF-8\"))?,\n                    args,\n                    work_dir.clone(),\n                    Duration::from_millis(timeout_ms),\n                )\n            }\n        } else {\n            CommandSpec::shell(command, work_dir.clone(), Duration::from_millis(timeout_ms))\n        };\n        let spec = spec.with_policy(policy).with_env(extra_env);\n        let exec_env = self.sandbox_manager.prepare(&spec);\n\n        if background {\n            let bounded_output = timeout_bounds_ms == (1, BASH_MAX_TIMEOUT_MS);\n            self.spawn_background_sandboxed(\n                command,\n                &work_dir,\n                &exec_env,\n                None,","sourceCodeStart":1995,"sourceCodeEnd":2031,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tools/shell.rs#L1995-L2031","documentation":"In hardened read-only shell mode, the command is parsed to argv (hardened_readonly_argv), the program is resolved against the workspace (resolve_readonly_program), and the resulting path is converted with Path::to_str() to build a CommandSpec::program. On Unix, paths are bytes and need not be valid UTF-8; to_str() returns None for such paths, so an executable (or workspace component) containing invalid UTF-8 bytes fails here.","triggerScenarios":"Running a read-only-mode command whose executable lives at a path with non-UTF-8 bytes (e.g. Latin-1 or otherwise invalid byte sequences in a filename), or where the workspace root itself contains such a component.","commonSituations":"Filesystems with legacy non-UTF-8 filenames; files created under a different locale; almost never hit on Windows (WTF-16 paths convert) — a Unix-specific edge.","solutions":["Rename or move the executable (or the offending path component) to a valid UTF-8 name.","Run the command outside read-only mode (plain shell mode takes a string command and does not require a UTF-8 program path).","Fix the workspace path if a parent directory carries non-UTF-8 bytes."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let program_path = resolve_program(command)?;\nanyhow::ensure!(\n    program_path.to_str().is_some(),\n    \"executable path {:?} is not valid UTF-8; rename it or use shell mode\",\n    program_path\n);\nexec_readonly(&command)?;","typeGuard":null,"tryCatchPattern":"match exec_readonly(&command) {\n    Ok(out) => out,\n    Err(e) if e.to_string().contains(\"not valid UTF-8\") => {\n        // Fall back to plain shell mode, which takes a string command\n        exec_shell(&command, None, None).await?\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Keep executables and workspace paths ASCII/UTF-8, especially on Unix where filenames are raw bytes.","When targeting arbitrary user filenames, prefer the string-command shell path over hardened read-only argv mode."],"tags":["shell","read-only","utf-8","path-encoding","unix"],"backgroundTag":"non-utf8-path","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}