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

the manifest-path must be a path to a Cargo.toml or script f

Error message

the manifest-path must be a path to a Cargo.toml or script file: `{}`

What it means

root_manifest, with `-Zscript` enabled, requires the manifest path to either end in `Cargo.toml` or be recognized by workspace::parser::is_embedded (a single `.rs` script with an embedded manifest). If the path is a file but matches neither, it bails. This is the script-aware variant of the manifest-path filename check.

Source

Thrown at src/util/command_prelude.rs:1070

        // In general, we try to avoid normalizing paths in Cargo,
        // but in this particular case we need it to fix #3586.
        let path = paths::normalize_path(&path);
        if !path.exists() {
            anyhow::bail!("manifest path `{}` does not exist", manifest_path.display())
        } else if path.is_dir() {
            let child_path = path.join("Cargo.toml");
            let suggested_path = if child_path.exists() {
                format!("\nhelp: {} exists", child_path.display())
            } else {
                "".to_string()
            };
            anyhow::bail!(
                "manifest path `{}` is a directory but expected a file{suggested_path}",
                manifest_path.display()
            )
        } else if !path.ends_with("Cargo.toml") && !crate::workspace::parser::is_embedded(&path) {
            if gctx.cli_unstable().script {
                anyhow::bail!(
                    "the manifest-path must be a path to a Cargo.toml or script file: `{}`",
                    path.display()
                )
            } else {
                anyhow::bail!(
                    "the manifest-path must be a path to a Cargo.toml file: `{}`",
                    path.display()
                )
            }
        }
        if crate::workspace::parser::is_embedded(&path) && !gctx.cli_unstable().script {
            anyhow::bail!("embedded manifest `{}` requires `-Zscript`", path.display())
        }
        Ok(path)
    } else {
        find_root_manifest_for_wd(gctx.cwd())
    }
}

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Point `--manifest-path` at a `Cargo.toml` or at a `.rs` file containing a valid embedded `//! ```cargo` manifest block.
  2. If the script lacks an embedded manifest, add one (the `cargo.nightly` code-fenced block at the top of the file).
  3. Remove `-Zscript` if you only intend to build a normal Cargo.toml project.

Example fix

# before (script.rs has no embedded manifest)
cargo run -Zscript --manifest-path script.rs

# after: ensure script.rs begins with
# //! ```cargo
# //! [dependencies]
# //! serde = "1"
# //! ```
cargo run -Zscript --manifest-path script.rs
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn validate_script_manifest(p: &Path) -> Result<(), anyhow::Error> {
    if !p.exists() { anyhow::bail!("missing"); }
    if p.is_dir() { anyhow::bail!("is a directory"); }
    let ok = p.ends_with("Cargo.toml") || cargo::workspace::parser::is_embedded(p);
    if !ok { anyhow::bail!("path must be Cargo.toml or an embedded-script .rs file"); }
    Ok(())
}

Type guard

fn is_cargo_script_or_manifest(p: &std::path::Path) -> bool {
    p.ends_with("Cargo.toml") || cargo::workspace::parser::is_embedded(p)
}

Try / catch

match root_manifest(Some(path), gctx) {
    Err(e) if e.to_string().contains("Cargo.toml or script file") => {
        eprintln!("with -Zscript, pass Cargo.toml or a .rs with an embedded manifest");
        return Err(e);
    }
    r => r,
}

Prevention

When it happens

Trigger: Running with `-Zscript` and `--manifest-path` pointing to a file that is neither `Cargo.toml` nor a recognized embedded-script `.rs` file (e.g. `Cargo.lock`, `README.md`, or a `.rs` file without a valid embedded manifest).

Common situations: Experimenting with cargo script (RFC 3424) and passing a non-script `.rs` file; passing the wrong file in a multi-file project; the script file lacks the leading `//! ```cargo` manifest block so is_embedded returns false.

Related errors


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