Hmbown/CodeWhale · error
workspace path cannot contain '..' components
Error message
workspace path cannot contain '..' components
What it means
checked_workspace_path rejects workspace paths containing any ParentDir ('..') component. Because the workspace root itself would be ambiguous after traversal, any '..' anywhere in the input is refused before canonicalization, regardless of whether normalization would resolve it back inside.
Source
Thrown at crates/tui/src/mcp.rs:3839
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))
}
Err(err) => {
Err(err).with_context(|| format!("failed to resolve workspace {}", workspace.display()))
}
}
}View on GitHub (pinned to 8880682c63)
Solutions
- Canonicalize the workspace path (std::fs::canonicalize) before passing it in
- Normalize away '..' components at the boundary where user input is accepted
- Reject '..' early in CLI validation with a clearer message
Example fix
// before
let ws = std::path::PathBuf::from("/home/me/proj/../proj2");
let cfg = checked_workspace_mcp_config_path(&ws)?;
// after
let ws = std::fs::canonicalize("/home/me/proj/../proj2")?;
let cfg = checked_workspace_mcp_config_path(&ws)?; Defensive patterns
Strategy: validation
Validate before calling
// Canonicalize user-supplied workspaces before use:
let workspace = std::fs::canonicalize(&raw_workspace)
.unwrap_or_else(|_| normalize_path_components(&raw_workspace));
anyhow::ensure!(!workspace.components().any(|c| matches!(c, std::path::Component::ParentDir)), "workspace contains '..'"); 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
- Canonicalize workspace paths at the input boundary (CLI, config load)
- Compose workspace paths with joins on absolute bases instead of string concatenation with '..'
- Add an integration test that feeds '..'-containing workspaces and asserts rejection
When it happens
Trigger: Passing a workspace like /home/me/proj/../proj2 or a relative ../repo into project MCP config resolution.
Common situations: Shell scripts composing paths with '..'; user-supplied --workspace arguments; config files storing unnormalized paths.
Related errors
- MCP config path cannot contain '..' components
- plugin registry workspace does not match MCP pool workspace
- workspace path cannot be empty
- ${name} is unavailable in Workflow scripts: runs must be det
- new Date()/Date() is unavailable in Workflow scripts: runs m
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/00fabcb95e11ebf4.
Report an issue: GitHub.