Hmbown/CodeWhale · error · anyhow::Error
{source} is not a directory: {}. Resume/fork from an existin
Error message
{source} is not a directory: {}. Resume/fork from an existing workspace or pass an explicit `working_dir`/`cwd` What it means
Before executing a shell command, the resolved working directory is stat'ed. A preceding check already handles the missing/unavailable path with a distinct message; this error fires when metadata exists but is not a directory (a regular file, socket, device, etc.). The message distinguishes whether the path came from a saved session workspace (inherited on resume/fork) or from an explicitly requested working directory, and names the offending path.
Source
Thrown at crates/tui/src/tools/shell.rs:142
fn validate_shell_working_dir(path: &Path, inherited_session_workspace: bool) -> Result<()> {
let metadata = std::fs::metadata(path).with_context(|| {
let source = if inherited_session_workspace {
"saved session workspace"
} else {
"requested working directory"
};
format!(
"{source} is unavailable: {}. Restore or remap that directory, resume/fork the session from an existing workspace, or pass an explicit `working_dir`/`cwd` to exec_shell",
path.display()
)
})?;
if !metadata.is_dir() {
let source = if inherited_session_workspace {
"saved session workspace"
} else {
"requested working directory"
};
return Err(anyhow!(
"{source} is not a directory: {}. Resume/fork from an existing workspace or pass an explicit `working_dir`/`cwd`",
path.display()
));
}
Ok(())
}
/// Status of a shell process.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ShellStatus {
Running,
Completed,
Failed,
Killed,
TimedOut,
}
/// Result from a shell command execution.View on GitHub (pinned to 0c42157ee5)
Solutions
- Pass an explicit working_dir/cwd that is an existing directory.
- If resuming/forking, resume from a session whose workspace directory actually exists, or remap the workspace.
- Check the path with ls/stat to confirm it is a directory, and fix the entry (remove the blocking file or correct the symlink).
Example fix
# before
exec_shell("cargo build", working_dir="./run.sh")
# after
exec_shell("cargo build", working_dir="./") Defensive patterns
Strategy: validation
Validate before calling
let dir: PathBuf = resolve_working_dir(requested, session)?;
if !dir.is_dir() {
anyhow::bail!("working directory {} is not a directory", dir.display());
}
exec_shell_with_dir(command, &dir)?; Try / catch
match exec_shell(cmd, Some(dir), None).await {
Ok(out) => out,
Err(e) if e.to_string().contains("is not a directory") => {
let fallback = current_workspace_root();
exec_shell(cmd, Some(&fallback), None).await?
}
Err(e) => return Err(e),
}; Prevention
- Always pass working_dir as a directory that exists right now — verify with is_dir() before the call.
- On resume/fork, validate the saved workspace still exists as a directory before running commands.
- When resuming on another machine, remap the workspace or pass an explicit working_dir/cwd.
When it happens
Trigger: Calling exec_shell with working_dir/cwd pointing at a file; or resuming/forking a session whose saved workspace path now exists but is not a directory (e.g. a file was created at that path).
Common situations: A symlink in the workspace path resolves to a file; the user passes a script path instead of its directory as cwd; on resume the old workspace was replaced by a file.
Related errors
- TTY mode requires background execution (set background: true
- The Codewhale service returned an account without an ID
- The Codewhale service returned an invalid user code
- The Codewhale service returned an invalid device authorizati
- API key must be {MIN_API_KEY_BYTES}-{MAX_API_KEY_BYTES} UTF-
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/c6e61576aca900a2.
Report an issue: GitHub.