{"id":"32c1a7881c5ae079","repo":"rust-lang/cargo","slug":"validation-ensures-this-is-a-table","errorCode":null,"errorMessage":"validation ensures this is a table","messagePattern":"validation ensures this is a table","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ops/lockfile.rs","lineNumber":188,"sourceCode":"        emit_package(dep, &mut out);\n    }\n\n    if let Some(patch) = toml.get(\"patch\") {\n        let list = patch[\"unused\"].as_array().unwrap();\n        for entry in list {\n            out.push_str(\"[[patch.unused]]\\n\");\n            emit_package(entry.as_table().unwrap(), &mut out);\n            out.push('\\n');\n        }\n    }\n\n    if let Some(meta) = toml.get(\"metadata\") {\n        // 1. We need to ensure we print the entire tree, not just the direct members of `metadata`\n        //    (which `toml_edit::Table::to_string` only shows)\n        // 2. We need to ensure all children tables have `metadata.` prefix\n        let meta_table = meta\n            .as_table()\n            .expect(\"validation ensures this is a table\")\n            .clone();\n        let mut meta_doc = toml::Table::new();\n        meta_doc.insert(\"metadata\".to_owned(), toml::Value::Table(meta_table));\n\n        out.push_str(&meta_doc.to_string());\n    }\n\n    // Historical versions of Cargo in the old format accidentally left trailing\n    // blank newlines at the end of files, so we just leave that as-is. For all\n    // encodings going forward, though, we want to be sure that our encoded lock\n    // file doesn't contain any trailing newlines so trim out the extra if\n    // necessary.\n    if resolve.version() >= ResolveVersion::V2 {\n        while out.ends_with(\"\\n\\n\") {\n            out.pop();\n        }\n    }\n    out","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/ops/lockfile.rs#L170-L206","documentation":"Invariant in lockfile encoding: `meta.as_table().expect(\"validation ensures this is a table\")`. When emitting `[metadata]` in `Cargo.lock`, cargo assumes the TOML value passed validation as a table. Lockfile metadata is validated upstream, so a non-table value here means validation was bypassed.","triggerScenarios":"Fires only if `Cargo.lock`'s `[metadata]` section parses to a non-table TOML value (array, string, etc.) that slipped past validation. Requires either a hand-edited lockfile with a malformed `[metadata]` or a cargo bug in the encode/decode round-trip.","commonSituations":"Hand-editing `Cargo.lock` and replacing `[metadata]` with a scalar/array; a cargo regression in lockfile metadata handling; a tool that rewrites `Cargo.lock` with an invalid metadata shape.","solutions":["Delete the `[metadata]` block from `Cargo.lock` (and regenerate with `cargo generate-lockfile` if needed).","Inspect `Cargo.lock` for a `[metadata]` that is not a table and fix its shape.","Report a cargo bug if no manual edit was made to the lockfile."],"exampleFix":"// before\nlet meta_table = meta.as_table().expect(\"validation ensures this is a table\").clone();\n\n// after\nlet meta_table = meta.as_table()\n    .ok_or_else(|| anyhow::format_err!(\"[metadata] in Cargo.lock is not a table\"))?\n    .clone();","handlingStrategy":"type-guard","validationCode":"// Before lockfile ops, assert [metadata] is a table.\nif let Some(meta) = lockfile_toml.get(\"metadata\") {\n    if !meta.is_table() {\n        return Err(anyhow!(\"Cargo.lock [metadata] is not a table\"));\n    }\n}","typeGuard":"fn metadata_is_table(v: &toml::Value) -> bool { matches!(v, toml::Value::Table(_)) }","tryCatchPattern":null,"preventionTips":["Never hand-edit `[metadata]` in `Cargo.lock` to a non-table value.","Use `cargo metadata` / tooling rather than direct lockfile rewrites.","Regenerate with `cargo generate-lockfile` after suspected corruption."],"tags":["cargo","panic","invariant","lockfile","toml","metadata","rust"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}