nikivdev/code · error
Relative path must not contain '..'.
Error message
Relative path must not contain '..'.
What it means
normalize_relative_path walks the path's components and rejects any ParentDir component, i.e. any `..` segment. Parent-directory traversal would let a crafted path escape the project root and operate on arbitrary locations, so the function refuses it as a path-traversal defense rather than resolving it lexically.
Source
Thrown at src/code.rs:812
fn normalize_path(path: &str) -> Result<PathBuf> {
let expanded = config::expand_path(path);
let canonical = expanded.canonicalize().unwrap_or(expanded);
Ok(canonical)
}
fn normalize_relative_path(path: &str) -> Result<PathBuf> {
let trimmed = path.trim();
if trimmed.is_empty() {
bail!("Relative path cannot be empty.");
}
let rel = PathBuf::from(trimmed);
if rel.is_absolute() {
bail!("Relative path must not be absolute.");
}
for component in rel.components() {
if matches!(component, std::path::Component::ParentDir) {
bail!("Relative path must not contain '..'.");
}
}
Ok(rel)
}
fn move_dir(from: &Path, to: &Path) -> Result<()> {
match fs::rename(from, to) {
Ok(()) => Ok(()),
Err(err) => {
if is_cross_device(&err) {
copy_dir_all(from, to)?;
fs::remove_dir_all(from)
.with_context(|| format!("failed to remove {}", from.display()))?;
Ok(())
} else {
Err(err).with_context(|| {
format!("failed to move {} to {}", from.display(), to.display())
})View on GitHub (pinned to a747e741ae)
Solutions
- Rephrase the destination as a path strictly under the root with no `..`, e.g. `"projects/foo"`.
- If the target truly must be outside the root, use the absolute-path API/flag instead of the relative one, if available.
- Sanitize incoming user input: reject or strip `..` segments before passing the value through.
- Compute sibling/parent destinations at the call site rather than encoding them in the relative argument.
Example fix
// before
normalize_relative_path("../neighbor-project")
// after
normalize_relative_path("neighbor-project") // lives under the tool's project root Defensive patterns
Strategy: validation
Validate before calling
let rel = Path::new(input.trim());
let has_parent = rel.components()
.any(|c| matches!(c, std::path::Component::ParentDir));
if has_parent {
return Err("path must not contain '..' segments".into());
} Type guard
fn is_safe_relative(s: &str) -> bool {
let p = Path::new(s.trim());
p.is_relative() && !p.components().any(|c| matches!(c, std::path::Component::ParentDir))
} Try / catch
match new_project(&rel) {
Err(e) if e.to_string().contains("must not contain '..'") => {
eprintln!("Place the project under the root; '..' traversal is not allowed.");
}
other => other?,
} Prevention
- Sanitize any user-supplied path input for '..' before use.
- Treat this as a security invariant for untrusted input (forms, APIs).
- Compute sibling/parent destinations outside the relative-path argument.
When it happens
Trigger: Calling new_project or migrate_project with a relative path containing `..`, e.g. `"../other-project"` or `"a/../../b"`.
Common situations: Users trying to place a project next to (rather than under) the root; scripts computing relative paths with `..`; untrusted input (web forms, generated configs) containing traversal sequences — deliberate or accidental.
Related errors
- Relative path cannot be empty.
- Relative path must not be absolute.
- Suggested command is incomplete.
- Command '{}' is incomplete.
- plan body is empty
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/3fdc2b5554191b84.
Report an issue: GitHub.