dbt-labs/dbt-core · error · anyhow

no `[workspace]` table

Error message

no `[workspace]` table

What it means

`write_workspace_version` in crates/dbt-ci/src/bump_cargo_version.rs parses a Cargo.toml with toml_edit and requires a `[workspace]` table to update the workspace package version. If the file parses as valid TOML but contains no `[workspace]` section, the lookup of the `workspace` key returns None and the function bails with this error. It guards against running the version-bump tool against a non-workspace manifest.

Source

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

                // Version write already succeeded; lockfile refresh is best-effort.
                eprintln!(
                    "warning: `cargo update --workspace --offline` failed. \
                     Version edits are applied; rerun lockfile refresh manually."
                );
            }
        }
    }

    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,

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Ensure the target Cargo.toml contains a `[workspace]` table (add one with at least `members = [...]` if converting to a workspace).
  2. Run the tool against the workspace-root Cargo.toml, not a member crate manifest.
  3. Check for typos in the table header (`[workspace]`, not `[workspaces]` or nesting under another table).

Example fix

// before (Cargo.toml)
[package]
name = "my-crate"
version = "0.1.0"
// after
[workspace]
members = ["crates/*"]

[workspace.package]
version = "0.1.0"

[package]
name = "my-crate"
version.workspace = true
Defensive patterns

Strategy: validation

Validate before calling

let src = std::fs::read_to_string(&path)?;
let doc: toml::Table = src.parse()?;
if !doc.contains_key("workspace") {
    return Err(format!("{} has no [workspace] table", path.display()));
}

Type guard

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

Try / catch

if let Err(e) = bump_version(&root_cargo_toml) {
    if e.to_string().contains("[workspace] table") {
        eprintln!("targeted the wrong Cargo.toml; use the workspace root");
    }
}

Prevention

When it happens

Trigger: Running the version bump command with a path to a Cargo.toml that has no `[workspace]` table — e.g. a plain single-package manifest, a `[workspace]` misspelled as `[workspaces]`, or the wrong file passed via the path argument.

Common situations: Pointing the bump tool at a member crate's Cargo.toml instead of the workspace root; migrating a repo from standalone-package layout to a workspace and forgetting to add the `[workspace]` table; a typo in the table header.

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/87df3c4a70a03713. Report an issue: GitHub.