nikivdev/code · error
Relative path must not be absolute.
Error message
Relative path must not be absolute.
What it means
normalize_relative_path enforces that the supplied path is relative: it rejects any value starting with `/` (or a platform root/drive prefix) via rel.is_absolute(). The library joins the sanitized path onto its own project root, so an absolute path would escape the intended root and write outside the managed directory.
Source
Thrown at src/code.rs:808
}
Ok(())
}
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(())View on GitHub (pinned to a747e741ae)
Solutions
- Pass only the folder name or a relative subpath, e.g. `"projects/foo"` instead of `/home/me/projects/foo`.
- Strip the known root prefix in your script: `rel="${abs#$ROOT/}"` before calling.
- Do not rely on `~` expansion — pass a relative name or expand it yourself and then convert to relative.
- Use Path::strip_prefix (or equivalent) to convert an absolute path to one relative to your base directory.
Example fix
// before
new_project("/home/alice/work/demo") // absolute → rejected
// after
new_project("work/demo") // relative to the tool's root Defensive patterns
Strategy: validation
Validate before calling
let rel = input.trim();
if Path::new(rel).is_absolute() {
return Err(format!("expected a relative path, got: {}", rel).into());
} Type guard
fn is_relative_path(s: &str) -> bool { Path::new(s.trim()).is_relative() } Try / catch
match new_project(&rel) {
Err(e) if e.to_string().contains("Relative path must not be absolute") => {
eprintln!("Pass a path relative to the tool's root, not an absolute one.");
}
other => other?,
} Prevention
- Document and enforce that this argument is a name/subpath, not a full path.
- Convert absolute inputs with strip_prefix against your base directory.
- Do not rely on `~` or `$HOME` expansion in this argument.
When it happens
Trigger: Calling new_project or migrate_project with a relative-path argument like `/tmp/project`, `C:\dev\project`, or `~/project` (tilde is not expanded and, after expansion, would be absolute).
Common situations: Users pasting absolute paths from their file manager; scripts using `$HOME/...` where a relative name was expected; Windows drive-letter paths leaking into cross-platform scripts; unexpanded `~` assumptions.
Related errors
- Relative path cannot be empty.
- Suggested command is incomplete.
- Command '{}' is incomplete.
- Relative path must not contain '..'.
- plan body is empty
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/e84b1a78f8a3e0c7.
Report an issue: GitHub.