{"id":"11bd1ffc4feceabf","repo":"rust-lang/cargo","slug":"bin-is-an-array-of-tables","errorCode":null,"errorMessage":"bin is an array of tables","messagePattern":"bin is an array of tables","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ops/cargo_new.rs","lineNumber":827,"sourceCode":"        array.push(registry);\n        manifest[\"package\"][\"publish\"] = toml_edit::value(array);\n    }\n    let dep_table = toml_edit::Table::default();\n    manifest[\"dependencies\"] = toml_edit::Item::Table(dep_table);\n\n    // Calculate what `[lib]` and `[[bin]]`s we need to append to `Cargo.toml`.\n    for i in &opts.source_files {\n        if i.bin {\n            if i.relative_path != \"src/main.rs\" {\n                let mut bin = toml_edit::Table::new();\n                bin[\"name\"] = toml_edit::value(name);\n                bin[\"path\"] = toml_edit::value(i.relative_path.clone());\n                manifest[\"bin\"]\n                    .or_insert(toml_edit::Item::ArrayOfTables(\n                        toml_edit::ArrayOfTables::new(),\n                    ))\n                    .as_array_of_tables_mut()\n                    .expect(\"bin is an array of tables\")\n                    .push(bin);\n            }\n        } else if i.relative_path != \"src/lib.rs\" {\n            let mut lib = toml_edit::Table::new();\n            lib[\"path\"] = toml_edit::value(i.relative_path.clone());\n            manifest[\"lib\"] = toml_edit::Item::Table(lib);\n        }\n    }\n\n    let manifest_path = paths::normalize_path(&path.join(\"Cargo.toml\"));\n    if let Ok(root_manifest_path) = find_root_manifest_for_wd(&manifest_path) {\n        let root_manifest = paths::read(&root_manifest_path)?;\n        // Sometimes the root manifest is not a valid manifest, so we only try to parse it if it is.\n        // This should not block the creation of the new project. It is only a best effort to\n        // inherit the workspace package keys.\n        if let Ok(mut workspace_document) = root_manifest.parse::<toml_edit::DocumentMut>() {\n            let display_path = get_display_path(&root_manifest_path, &path)?;\n            let can_be_a_member = can_be_workspace_member(&display_path, &workspace_document)?;","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/ops/cargo_new.rs#L809-L845","documentation":"Invariant in `cargo new`'s manifest builder. When a binary source file is detected (not `src/main.rs`), the code does `manifest[\"bin\"].or_insert(Item::ArrayOfTables(ArrayOfTables::new())).as_array_of_tables_mut().expect(\"bin is an array of tables\")`. Because the value is either pre-existing as `ArrayOfTables` or just inserted as one, the downcast cannot fail — the panic guards a toml_edit shape assumption.","triggerScenarios":"Reachable only if `manifest[\"bin\"]` already exists in the `Cargo.toml` template as a non-array-of-tables value (e.g. a user supplied a `bin = \"string\"` or `[bin]` table in a custom template), which would make `or_insert` a no-op and `as_array_of_tables_mut()` return `None`.","commonSituations":"Using `cargo new --bin` with a custom/patched cargo that pre-populates `manifest[\"bin\"]` with the wrong shape; corrupt template injection in `cargo_new.rs::write_bare_version`/`MkOptions`. End users invoking standard `cargo new` cannot trigger it.","solutions":["Report as a cargo bug if reproduced with stock `cargo new`.","If using a custom cargo build, ensure any pre-existing `[bin]`/`bin` key in the manifest template is shaped as `[[bin]]` array-of-tables before this code runs.","Validate the template with `toml_edit` and normalize `bin` to `ArrayOfTables` before entering the loop."],"exampleFix":"// before\nmanifest[\"bin\"]\n    .or_insert(toml_edit::Item::ArrayOfTables(toml_edit::ArrayOfTables::new()))\n    .as_array_of_tables_mut()\n    .expect(\"bin is an array of tables\")\n    .push(bin);\n\n// after (explicit shape check with a clear error)\nlet bins = match manifest.entry(\"bin\").or_insert_with(||\n    toml_edit::Item::ArrayOfTables(toml_edit::ArrayOfTables::new())) {\n    toml_edit::Item::ArrayOfTables(t) => t,\n    other => bail!(\"`bin` must be an array of tables, found {:?}\", other.type_name()),\n};\nbins.push(bin);","handlingStrategy":"validation","validationCode":"// If you generate Cargo.toml templates consumed by cargo new, validate shape first.\nif let Some(bin) = manifest.get(\"bin\") {\n    assert!(matches!(bin, toml_edit::Item::ArrayOfTables(_)),\n        \"[bin] must be an array of tables, got {:?}\", bin.type_name());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not pre-populate a `bin` key in custom cargo-new templates; let cargo manage it.","Run `cargo new` on clean templates; inspect the generated manifest before scripting over it."],"tags":["cargo","panic","invariant","cargo-new","toml-edit","rust"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}