Hmbown/CodeWhale · error
workspace path cannot be empty
Error message
workspace path cannot be empty
What it means
checked_workspace_path is the entry guard for workspace-scoped MCP config lookups. An empty workspace string cannot identify a workspace, so it is rejected immediately, before any path is joined or the filesystem is touched.
Source
Thrown at crates/tui/src/mcp.rs:3833
if !resolved.starts_with(plugin_path) {
anyhow::bail!("reviewed plugin MCP path escaped its staged root");
}
Ok(resolved)
}
fn workspace_allows_project_mcp_config(workspace: &Path) -> bool {
crate::config::is_workspace_trusted(workspace)
}
fn checked_workspace_mcp_config_path(workspace: &Path) -> Result<PathBuf> {
Ok(checked_workspace_path(workspace)?
.join(".codewhale")
.join("mcp.json"))
}
fn checked_workspace_path(workspace: &Path) -> Result<PathBuf> {
if workspace.as_os_str().is_empty() {
anyhow::bail!("workspace path cannot be empty");
}
if workspace
.components()
.any(|component| matches!(component, Component::ParentDir))
{
anyhow::bail!("workspace path cannot contain '..' components");
}
let absolute = if workspace.is_absolute() {
workspace.to_path_buf()
} else {
std::env::current_dir()
.context("failed to resolve current directory for workspace")?
.join(workspace)
};
match absolute.canonicalize() {
Ok(path) => Ok(path),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
Ok(normalize_path_components(&absolute))View on GitHub (pinned to 8880682c63)
Solutions
- Pass a non-empty workspace path (preferably absolute) from the caller
- Default to std::env::current_dir() when the workspace is unknown
- Fix the upstream config/CLI plumbing that produced the empty string
Example fix
// before
let path = checked_workspace_mcp_config_path(Path::new(&workspace_var))?;
// after
let workspace = if workspace_var.is_empty() {
std::env::current_dir()?
} else {
PathBuf::from(&workspace_var)
};
let path = checked_workspace_mcp_config_path(&workspace)?; Defensive patterns
Strategy: validation
Validate before calling
// Reject empty workspaces at the boundary before any MCP config lookup:
let workspace = if workspace_input.as_os_str().is_empty() {
std::env::current_dir().context("no workspace supplied; using cwd")?
} else {
workspace_input.to_path_buf()
};
let mcp_path = checked_workspace_mcp_config_path(&workspace)?; Type guard
fn is_usable_workspace(p: &std::path::Path) -> bool {
!p.as_os_str().is_empty()
&& !p.components().any(|c| matches!(c, std::path::Component::ParentDir))
} Prevention
- Validate the workspace argument once at CLI/config parse time and fail with context
- Default empty workspace inputs to the current directory instead of forwarding them
- Log the resolved absolute workspace at startup to catch plumbing mistakes early
When it happens
Trigger: Passing an empty workspace (an unpopulated config field, an env var that expanded to nothing, or an empty string from argument parsing) into project MCP config loading or the checked_workspace_mcp_config_path helper.
Common situations: Calling workspace MCP helpers from scripts or tests with an uninitialized workspace variable; a launcher that starts the TUI before setting the workspace.
Related errors
- plugin registry workspace does not match MCP pool workspace
- workspace path cannot contain '..' components
- ${name} is unavailable in Workflow scripts: runs must be det
- new Date()/Date() is unavailable in Workflow scripts: runs m
- task(): expected an options object
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/ee344c0bcdb5a1e9.
Report an issue: GitHub.