bevyengine/bevy · critical
Unable to read cargo manifest: {}
Error message
Unable to read cargo manifest: {} What it means
bevy_macro_utils' BevyManifest::read_manifest panics when Cargo.toml at the derived CARGO_MANIFEST_DIR path cannot be read (crates/bevy_macro_utils/src/bevy_manifest.rs:76). Bevy proc macros use this at compile time to resolve sibling crate paths, so the panic aborts compilation of any crate expanding Bevy macros.
Source
Thrown at crates/bevy_macro_utils/src/bevy_manifest.rs:76
assert!(
path.exists(),
"Cargo manifest does not exist at path {}",
path.display()
);
path
})
.expect("CARGO_MANIFEST_DIR is not defined.")
}
fn get_manifest_modified_time(
cargo_manifest_path: &Path,
) -> Result<SystemTime, std::io::Error> {
std::fs::metadata(cargo_manifest_path).and_then(|metadata| metadata.modified())
}
fn read_manifest(path: &Path) -> Document<Box<str>> {
let manifest = std::fs::read_to_string(path)
.unwrap_or_else(|_| panic!("Unable to read cargo manifest: {}", path.display()))
.into_boxed_str();
Document::parse(manifest)
.unwrap_or_else(|_| panic!("Failed to parse cargo manifest: {}", path.display()))
}
/// Attempt to retrieve the [path](syn::Path) of a particular package in
/// the [manifest](BevyManifest) by [name](str).
pub fn maybe_get_path(&self, name: &str) -> Option<syn::Path> {
// Cargo normalizes hyphens to underscores when crates are referenced from Rust code.
let rust_name = name.replace('-', "_");
let find_in_deps = |deps: &Item| -> Option<syn::Path> {
let package = if deps.get(name).is_some() {
return Some(Self::parse_str(&rust_name));
} else if deps.get(BEVY).is_some() {
BEVY
} else {
// Note: to support bevy crate aliases, we could do scanning here to find a crate with a "package" name that
// matches our request, but that would then mean we are scanning every dependency (and dev dependency) for everyView on GitHub (pinned to 396ca72708)
Solutions
- Run cargo clean and rebuild from a quiescent, unmodified source tree.
- Verify Cargo.toml exists and is readable in the failing crate's directory (check the path printed in the panic).
- Allowlist the project in antivirus/sandbox tools or move off flaky network filesystems so the manifest cannot be locked or disappear during macro expansion.
Example fix
// before: cargo build fails with 'Unable to read cargo manifest: .../Cargo.toml' // after cargo clean cargo build # rebuild with no concurrent edits to the source tree
Defensive patterns
Strategy: retry
Validate before calling
# pre-build sanity check (CI or wrapper script):
test -f "${CARGO_MANIFEST_DIR:-.}/Cargo.toml" || {
echo "Cargo.toml missing/unreadable; restore sources before building"; exit 1;
} Prevention
- Do not edit, move, or delete sources while cargo is building.
- After interrupted builds, run cargo clean before rebuilding.
- Allowlist the workspace in antivirus/sandbox tools so Cargo.toml is never locked.
- Prefer stable local filesystems over network mounts for Bevy macro builds.
When it happens
Trigger: Compiling a crate that uses Bevy macros while its Cargo.toml is missing or unreadable mid-build: interrupted builds, sources moved/deleted during compile, sandbox/permission/antivirus locks on the manifest, or a corrupted target cache pointing at stale paths.
Common situations: CI cache corruption; builds on network filesystems where the manifest briefly vanishes; antivirus or sandbox tooling locking Cargo.toml; editing or moving files while cargo runs; unusual workspaces with generated manifests.
Related errors
- bevy_ecs should be found in manifest
- conflicting type data registration
- Caching entries after the first is not supported, remove the
- Consts are not currently supported in this position
- Currently, caching is only supported for scene assets. Pleas
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/1baa425b04b41492.
Report an issue: GitHub.