bevyengine/bevy · error

Failed to parse cargo manifest: {}

Error message

Failed to parse cargo manifest: {}

What it means

This panic is raised inside Bevy's proc-macro support code when a derive macro (any bevy derive that resolves crate paths via BevyManifest) tries to read and parse the workspace Cargo.toml and the TOML parser fails. The manifest is read at compile time during macro expansion, so a malformed Cargo.toml turns into a hard build failure with this message. The sibling panic 'Unable to read cargo manifest' covers I/O failures, while this one means the file was read but is not parseable TOML.

Source

Thrown at crates/bevy_macro_utils/src/bevy_manifest.rs:79

                    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 every
                // macro execution that hits this branch (which includes all built-in bevy crates). Our current stance is that supporting
                // remapped crate names in derive macros is not worth that "compile time" price of admission. As a workaround, people aliasing
                // bevy crate names can use "use REMAPPED as bevy_X" or "use REMAPPED::x as bevy_x".

View on GitHub (pinned to 396ca72708)

Solutions

  1. Run `cargo metadata --format-version 1 --no-deps` — if it errors, the TOML syntax error (with line/column) is reported; fix that spot in Cargo.toml.
  2. Search Cargo.toml for merge-conflict markers (<<<<<<<, =======, >>>>>>>) and resolve them.
  3. Verify the file is valid UTF-8 without BOM (`file Cargo.toml` or `iconv -f utf-8 -t utf-8 Cargo.toml -o /dev/null`).
  4. If an external tool generates the manifest, regenerate it and confirm the produced TOML with a linter (e.g. `taplo check` or `toml` parse in a scratch script).

Example fix

# before (Cargo.toml — broken after a merge)
[dependencies
bevy = "0.14"
<<<<<<< HEAD
bevy_math = "0.14"
=======
bevy_transform = "0.14"
>>>>>>>

# after
[dependencies]
bevy = "0.14"
bevy_math = "0.14"
Defensive patterns

Strategy: validation

Validate before calling

# CI gate (shell) — fails fast with a precise TOML error before any bevy macro runs:
cargo metadata --format-version 1 --no-deps > /dev/null || echo "Cargo.toml is not valid TOML"

Prevention

When it happens

Trigger: Any bevy derive macro (e.g. #[derive(Component)], #[derive(Bundle)], #[derive(Resource)]) expanding in a crate whose Cargo.toml contains invalid TOML syntax — unbalanced brackets, merge-conflict markers (<<<<<<<), duplicate table headers, or non-UTF-8 bytes. Also triggered when rust-analyzer or an out-of-sync build reads a partially-saved/hand-edited manifest.

Common situations: Git merge conflicts left in Cargo.toml; manual edits that break TOML syntax; BOM or encoding issues; editors writing the file mid-save while cargo check runs; rare cases where cargo tolerates the file but toml_edit's stricter parse rejects it after a toolchain or bevy version bump.

Understand the failure class

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/8d1a06f33bd4e03a. Report an issue: GitHub.