dbt-labs/dbt-core · error · anyhow

no `[workspace.package]` table

Error message

no `[workspace.package]` table

What it means

`write_workspace_version` in crates/dbt-ci/src/bump_cargo_version.rs found a `[workspace]` table but no `[workspace.package]` table inside it. Since the version bump writes to `workspace.package.version`, the absence of the inner `package` table causes this bail. It indicates a partially converted or non-standard workspace manifest.

Source

Thrown at crates/dbt-ci/src/bump_cargo_version.rs:64

                );
            }
        }
    }

    ExitCode::SUCCESS
}

fn write_workspace_version(path: &Path, new_value: &str) -> Result<()> {
    let src = fs::read_to_string(path).with_context(|| format!("read {}", path.display()))?;
    let mut doc: DocumentMut = src.parse().context("parse Cargo.toml")?;
    let workspace = doc
        .get_mut("workspace")
        .and_then(|w| w.as_table_like_mut())
        .ok_or_else(|| anyhow!("no `[workspace]` table"))?;
    let package = workspace
        .get_mut("package")
        .and_then(|p| p.as_table_like_mut())
        .ok_or_else(|| anyhow!("no `[workspace.package]` table"))?;
    package.insert("version", value(new_value));
    fs::write(path, doc.to_string()).with_context(|| format!("write {}", path.display()))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn write_workspace_version_overwrites_existing() {
        let tmp = tempfile::tempdir().unwrap();
        let path = tmp.path().join("Cargo.toml");
        fs::write(
            &path,
            r#"[workspace.package]
edition = "2024"
version = "2.0.0-preview-nightly.176"
authors = ["dbt Labs"]

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Add a `[workspace.package]` table containing `version = "x.y.z"` to the workspace-root Cargo.toml.
  2. Switch member crates to inherit: `version.workspace = true` under `[package]`.
  3. Verify the `[workspace.package]` header is at top level, not indented under another table (it must not be inside an array-of-tables or sub-table).

Example fix

// before (Cargo.toml)
[workspace]
members = ["crates/*"]
// after
[workspace]
members = ["crates/*"]

[workspace.package]
version = "1.2.3"
Defensive patterns

Strategy: validation

Validate before calling

let doc: toml::Table = std::fs::read_to_string(&path)?.parse()?;
let has_ws_pkg = doc.get("workspace")
    .and_then(|w| w.get("package"))
    .and_then(|p| p.as_table())
    .map(|t| t.contains_key("version"))
    .unwrap_or(false);
if !has_ws_pkg {
    return Err(format!("{} has no [workspace.package] version", path.display()));
}

Type guard

fn has_workspace_package(doc: &toml::Value) -> bool {
    doc.get("workspace")
        .and_then(|w| w.get("package"))
        .and_then(|p| p.as_table())
        .is_some()
}

Try / catch

if let Err(e) = bump_version(&root_cargo_toml) {
    if e.to_string().contains("[workspace.package] table") {
        eprintln!("add [workspace.package] with a version key first");
    }
}

Prevention

When it happens

Trigger: The Cargo.toml has a `[workspace]` table (with members, dependencies, etc.) but defines no `[workspace.package]` section, so `workspace.get_mut("package")` returns None. Also triggered when `package` exists but as a non-table value (e.g. a stray string).

Common situations: A workspace that pins versions per-crate instead of using `version.workspace = true` inheritance; a repo mid-migration to workspace-inherited versions; `[workspace.package]` header typoed or accidentally nested under another table.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/96d5f1debcca057b. Report an issue: GitHub.