rust-lang/cargo · error · anyhow::Error
manifest path `{}` is a directory but expected a file{sugges
Error message
manifest path `{}` is a directory but expected a file{suggested_path} What it means
root_manifest checks that `--manifest-path` exists and is NOT a directory. If the path is a directory, Cargo bails and, when a `Cargo.toml` child exists inside it, appends a help line suggesting that file. Cargo expects a file path, not a folder.
Source
Thrown at src/util/command_prelude.rs:1064
args._values_of_os(name)
}
pub fn root_manifest(manifest_path: Option<&Path>, gctx: &GlobalContext) -> CargoResult<PathBuf> {
if let Some(manifest_path) = manifest_path {
let path = gctx.cwd().join(manifest_path);
// 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())View on GitHub (pinned to 0e07a15537)
Solutions
- Append `Cargo.toml`: `cargo build --manifest-path ./mycrate/Cargo.toml`.
- If the help line suggests a path, use exactly that path.
- Drop `--manifest-path` and `cd` into the directory so Cargo auto-discovers Cargo.toml.
Example fix
# before cargo build --manifest-path ./mycrate # after cargo build --manifest-path ./mycrate/Cargo.toml
Defensive patterns
Strategy: validation
Validate before calling
use std::path::Path;
fn ensure_manifest_is_file(p: &Path) -> Result<(), anyhow::Error> {
if !p.exists() { anyhow::bail!("{p:?} missing"); }
if p.is_dir() { anyhow::bail!("{p:?} is a directory; append Cargo.toml"); }
Ok(())
} Type guard
fn is_manifest_file(p: &std::path::Path) -> bool {
p.is_file() && p.file_name().map(|n| n == "Cargo.toml").unwrap_or(false)
} Try / catch
match root_manifest(Some(path), gctx) {
Err(e) if e.to_string().contains("is a directory") => {
eprintln!("pass the Cargo.toml file, not its directory");
return Err(e);
}
r => r,
} Prevention
- Always append `Cargo.toml` when the path is a directory.
- Watch for IDE auto-complete completing to the folder.
When it happens
Trigger: Passing a directory to `--manifest-path`: `cargo build --manifest-path ./mycrate` where `mycrate/` is a folder (commonly one that contains a Cargo.toml).
Common situations: Pointing `--manifest-path` at the crate directory rather than its Cargo.toml; muscle memory from tools that accept a directory; scripts that pass `${PROJECT_DIR}` instead of `${PROJECT_DIR}/Cargo.toml`.
Related errors
- manifest path `{}` does not exist
- the manifest-path must be a path to a Cargo.toml or script f
- the manifest-path must be a path to a Cargo.toml file: `{}`
- embedded manifest `{}` requires `-Zscript`
- could not find `{}` in `{}` or any parent directory, but fou
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/3efbb459fb3d482a.json.
Report an issue: GitHub.