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 `..` components to guarantee the derived `.codewhale/mcp.json` location stays unambiguous and cannot traverse outside the intended workspace. The library treats parent-dir components in a workspace root as invalid input rather than normalizing them away.
Solutions
- Canonicalize the workspace before passing it in: `workspace.canonicalize()?` removes `..` components
- Convert the path to an absolute path via `std::env::current_dir()?.join(rel)` then `normalize_path_components`
- Fix the stored configuration to use an absolute, `..`-free workspace path
Example fix
// before
let workspace = PathBuf::from("../other-project");
// after
let workspace = PathBuf::from("../other-project").canonicalize()?; // absolute, no '..' components Defensive patterns
Strategy: validation
Validate before calling
use std::path::Component;
if workspace.components().any(|c| matches!(c, Component::ParentDir)) {
let workspace = workspace.canonicalize()?;
} Type guard
fn has_parent_components(p: &std::path::Path) -> bool {
p.components().any(|c| matches!(c, Component::ParentDir))
} Try / catch
let workspace = workspace.canonicalize().map_err(|e| anyhow::anyhow!("cannot normalize workspace {workspace:?}: {e}"))?; Prevention
- Canonicalize user-supplied paths before storing them in config
- Use absolute paths for workspace settings
- Reject or normalize '..' at the config-parsing layer
When it happens
Trigger: Passing a workspace like `Path::new("../myproject")` or `./a/../b` into any MCP config function that routes through `checked_workspace_path` (crates/tui/src/mcp.rs:5619).
Common situations: Users typing relative `../` paths on the command line; scripts building workspace paths by concatenation; config values copied with trailing relative segments.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- workspace path cannot be empty
- MCP config path cannot be empty
- project workspace path cannot be empty
- workspace must not be empty
- AutomationEditorInvalidWorkspace
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/00fabcb95e11ebf4.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp.rs:5619
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 73e0f67d83)