Hmbown/CodeWhale · error · anyhow::Error
project workspace path cannot contain '..' components
Error message
project workspace path cannot contain '..' components
What it means
Thrown by normalize_project_workspace when the workspace path contains a '..' (ParentDir) component. This is the same anti-traversal guard as the config path normalizer, applied to lane/project workspace roots; the input must be expressible without parent references before canonicalization is attempted.
Source
Thrown at crates/config/src/lib.rs:6660
return Err(err).with_context(|| {
format!("failed to resolve config directory {}", parent.display())
});
}
};
let normalized = parent.join(file_name);
reject_path_symlink(&normalized)?;
Ok(normalized)
}
fn normalize_project_workspace(workspace: &Path) -> Result<PathBuf> {
if workspace.as_os_str().is_empty() {
bail!("project workspace path cannot be empty");
}
if workspace
.components()
.any(|component| matches!(component, Component::ParentDir))
{
bail!("project 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 project 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 project workspace {}",
workspace.display()
)View on GitHub (pinned to 0c42157ee5)
Solutions
- Pass an absolute, '..'-free path to the workspace (pwd-realpath it first if needed)
- Use a path relative to the current directory that descends only, e.g. worktrees/feature-x
- Generate paths with realpath/CanonPath in your launcher so they never contain '..'
Example fix
# before workspace = "../repo" # after workspace = "/home/user/repo"
Defensive patterns
Strategy: validation
Validate before calling
use std::path::{Component, Path};
anyhow::ensure!(
!workspace.components().any(|c| matches!(c, Component::ParentDir)),
"workspace path must not contain '..'"
); Type guard
fn workspace_is_traversal_free(p: &std::path::Path) -> bool {
!p.components().any(|c| matches!(c, std::path::Component::ParentDir))
} Prevention
- Pass absolute worktree paths you obtained from realpath/git worktree list
- Reject '..' in user-supplied workspace paths before they reach the lane API
When it happens
Trigger: workspace = "../repo", "../../team/worktree", or any relative path walking upward from the current directory. The components check runs before the canonicalize/fallback step, so even a lexically-cancelling '..' is rejected.
Common situations: Monorepo scripts addressing sibling worktrees via ../; CI jobs checking out to nested dirs and passing ../../workspace; attempts to escape a sandbox root by '..'.
Related errors
- persistent allow rules must be scoped to a workspace
- persistent path allow rules must stay within the workspace
- config path cannot contain '..' components
- project workspace path cannot be empty
- {kind} must be a single path component
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/d216f31a1d13e1c9.
Report an issue: GitHub.