rust-lang/cargo · error · anyhow::Error

can only edit absolute paths, got {}

Error message

can only edit absolute paths, got {}

What it means

Thrown by `LocalManifest::try_new` at src/workspace/editor/manifest.rs:268. The manifest editor (used by `cargo add`, `cargo rm`, and library callers) requires an absolute filesystem path so it can reliably read, normalize, and write back the file. A relative path is rejected immediately before any I/O.

Source

Thrown at src/workspace/editor/manifest.rs:268

impl Deref for LocalManifest {
    type Target = Manifest;

    fn deref(&self) -> &Manifest {
        &self.manifest
    }
}

impl DerefMut for LocalManifest {
    fn deref_mut(&mut self) -> &mut Manifest {
        &mut self.manifest
    }
}

impl LocalManifest {
    /// Construct the `LocalManifest` corresponding to the `Path` provided..
    pub fn try_new(path: &Path) -> CargoResult<Self> {
        if !path.is_absolute() {
            anyhow::bail!("can only edit absolute paths, got {}", path.display());
        }
        let raw = cargo_util::paths::read(&path)?;
        let mut data = raw.clone();
        let mut embedded = None;
        if is_embedded(path) {
            let source = ScriptSource::parse(&data)?;
            if let Some(frontmatter) = source.frontmatter_span() {
                embedded = Some(Embedded::exists(frontmatter));
                data = source.frontmatter().unwrap().to_owned();
            } else if let Some(shebang) = source.shebang_span() {
                embedded = Some(Embedded::after(shebang));
                data = String::new();
            } else {
                embedded = Some(Embedded::start());
                data = String::new();
            }
        }
        let manifest = data.parse().context("unable to parse Cargo.toml")?;

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Canonicalize first: `LocalManifest::try_new(&std::fs::canonicalize(p)?)`.
  2. Make the path absolute with the current dir: `let p = std::env::current_dir()?.join(p); LocalManifest::try_new(&p)`.
  3. Ensure callers always pass an absolute path to the editor API.

Example fix

// before
let m = LocalManifest::try_new(Path::new("Cargo.toml"))?;
// after
let abs = std::env::current_dir()?.join("Cargo.toml");
let m = LocalManifest::try_new(&abs)?;
Defensive patterns

Strategy: validation

Validate before calling

let abs = if p.is_absolute() { p.to_path_buf() }
    else { std::env::current_dir()?.join(p) };
assert!(abs.is_absolute(), "path must be absolute");
let m = LocalManifest::try_new(&abs)?;

Type guard

fn is_absolute_manifest_path(p: &std::path::Path) -> bool { p.is_absolute() }

Prevention

When it happens

Trigger: Calling `LocalManifest::try_new(Path::new("Cargo.toml"))` or `try_new(&relative)` from a tool; `cargo add` invoked with a manifest path resolved relative to the wrong cwd.

Common situations: Embedding cargo-as-a-library and passing a user-supplied relative path; glue code that joins paths incorrectly; running under a changed working directory.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/a848e905967ee656.json. Report an issue: GitHub.