rust-lang/cargo · error
bin is an array of tables
Error message
bin is an array of tables
What it means
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.
Source
Thrown at src/ops/cargo_new.rs:827
array.push(registry);
manifest["package"]["publish"] = toml_edit::value(array);
}
let dep_table = toml_edit::Table::default();
manifest["dependencies"] = toml_edit::Item::Table(dep_table);
// Calculate what `[lib]` and `[[bin]]`s we need to append to `Cargo.toml`.
for i in &opts.source_files {
if i.bin {
if i.relative_path != "src/main.rs" {
let mut bin = toml_edit::Table::new();
bin["name"] = toml_edit::value(name);
bin["path"] = toml_edit::value(i.relative_path.clone());
manifest["bin"]
.or_insert(toml_edit::Item::ArrayOfTables(
toml_edit::ArrayOfTables::new(),
))
.as_array_of_tables_mut()
.expect("bin is an array of tables")
.push(bin);
}
} else if i.relative_path != "src/lib.rs" {
let mut lib = toml_edit::Table::new();
lib["path"] = toml_edit::value(i.relative_path.clone());
manifest["lib"] = toml_edit::Item::Table(lib);
}
}
let manifest_path = paths::normalize_path(&path.join("Cargo.toml"));
if let Ok(root_manifest_path) = find_root_manifest_for_wd(&manifest_path) {
let root_manifest = paths::read(&root_manifest_path)?;
// Sometimes the root manifest is not a valid manifest, so we only try to parse it if it is.
// This should not block the creation of the new project. It is only a best effort to
// inherit the workspace package keys.
if let Ok(mut workspace_document) = root_manifest.parse::<toml_edit::DocumentMut>() {
let display_path = get_display_path(&root_manifest_path, &path)?;
let can_be_a_member = can_be_workspace_member(&display_path, &workspace_document)?;View on GitHub (pinned to 0e07a15537)
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.
Example fix
// before
manifest["bin"]
.or_insert(toml_edit::Item::ArrayOfTables(toml_edit::ArrayOfTables::new()))
.as_array_of_tables_mut()
.expect("bin is an array of tables")
.push(bin);
// after (explicit shape check with a clear error)
let bins = match manifest.entry("bin").or_insert_with(||
toml_edit::Item::ArrayOfTables(toml_edit::ArrayOfTables::new())) {
toml_edit::Item::ArrayOfTables(t) => t,
other => bail!("`bin` must be an array of tables, found {:?}", other.type_name()),
};
bins.push(bin); Defensive patterns
Strategy: validation
Validate before calling
// If you generate Cargo.toml templates consumed by cargo new, validate shape first.
if let Some(bin) = manifest.get("bin") {
assert!(matches!(bin, toml_edit::Item::ArrayOfTables(_)),
"[bin] must be an array of tables, got {:?}", bin.type_name());
} Prevention
- 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.
When it happens
Trigger: 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`.
Common situations: 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.
Related errors
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/11bd1ffc4feceabf.json.
Report an issue: GitHub.