Hmbown/CodeWhale · error
read-only executable path is not valid UTF-8
Error message
read-only executable path is not valid UTF-8
What it means
When a command runs under the hardened read-only policy, the resolved executable path (a PathBuf/OsStr) must be convertible to valid UTF-8 to be passed as a string program name into CommandSpec. If the resolved path contains non-UTF-8 bytes (e.g. unusual bytes in a directory name), the code refuses with this error rather than silently mis-handling the path.
Solutions
- Rename the executable and/or its parent directories to use valid UTF-8 names.
- Install or reference the binary via a UTF-8-safe path (e.g. symlink it into /usr/local/bin or another ASCII path).
- Check PATH and workspace root for non-UTF-8 components and fix the environment; on Unix you can inspect bytes with `path.as_os_str().as_bytes()`.
Example fix
// before PATH=/home/user/biné:/usr/bin # non-UTF-8 dir in PATH resolves tool from bad path // after ln -s /opt/tools/bin/mytool /usr/local/bin/mytool # then invoke via the UTF-8-safe /usr/local/bin/mytool
Defensive patterns
Strategy: validation
Validate before calling
// check the resolved program is UTF-8 before running the read-only command
let program = resolve_readonly_program(&program, workspace)?;
if program.to_str().is_none() {
return Err(anyhow!(
"executable path {:?} contains non-UTF-8 bytes; rename or symlink it",
program
));
} Try / catch
// catch and guide the user to fix the environment
match run_readonly(command) {
Err(e) if e.to_string().contains("not valid UTF-8") => {
eprintln!("Binary path has non-UTF-8 characters; symlink it to a UTF-8-safe path.");
}
other => other?,
} Prevention
- Keep PATH and workspace directories free of non-UTF-8 names.
- Symlink non-UTF-8-named binaries into an ASCII path like /usr/local/bin.
- Audit environment/workspace paths with a UTF-8 validity check at startup.
When it happens
Trigger: Running a read-only sandboxed command whose resolved program path — after resolve_readonly_program against the workspace — contains non-UTF-8 bytes, e.g. a binary installed under a directory with Latin-1/invalid-UTF-8 characters in its name.
Common situations: PATH pointing at a directory with non-UTF-8 characters; a workspace path created by a tool that wrote raw bytes into filenames; filesystems that permit non-UTF-8 names (common on Linux).
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- artifact name is not portable UTF-8
- child stdout was not valid UTF-8
- Configuration and skill entrypoints must be UTF-8.
- current Codewhale executable path is not valid UTF-8
- {err}
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/f02380d563e1a8ff.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/shell.rs:2166
validate_shell_working_dir(&work_dir, working_dir.is_none())?;
let timeout_ms = timeout_ms.clamp(timeout_bounds_ms.0, timeout_bounds_ms.1);
// Use override policy if provided, otherwise use the manager's policy
let policy = policy_override.unwrap_or_else(|| self.sandbox_policy.clone());
// Create command spec and prepare sandboxed environment
let spec = if let Some(workspace) = readonly_workspace {
if command.contains('|') {
let piped = hardened_readonly_pipeline(command, workspace)?;
CommandSpec::shell(&piped, work_dir.clone(), Duration::from_millis(timeout_ms))
} else {
let (program, args) = hardened_readonly_argv(command)?;
let program = resolve_readonly_program(&program, workspace)?;
CommandSpec::program(
program
.to_str()
.ok_or_else(|| anyhow!("read-only executable path is not valid UTF-8"))?,
args,
work_dir.clone(),
Duration::from_millis(timeout_ms),
)
}
} else {
CommandSpec::shell(command, work_dir.clone(), Duration::from_millis(timeout_ms))
};
let spec = spec.with_policy(policy).with_env(extra_env);
let exec_env = self.sandbox_manager.prepare(&spec);
if matches!(spec.sandbox_policy, ExecutionSandboxPolicy::ReadOnly)
&& readonly_workspace.is_none()
{
// Arbitrary code with a read-only policy needs kernel enforcement;
// only the separately hardened argv subset may run without it.
require_native_readonly_execution(&exec_env)?;
}
View on GitHub (pinned to 73e0f67d83)