clockworklabs/SpacetimeDB · error · std::io::Error
workspace manifest is not a table
Error message
workspace manifest is not a table
What it means
Runtime error in the spacetimedb CLI's build script (crates/cli/build.rs). While compiling the CLI, the script parses the repository-root Cargo.toml to embed the workspace edition and dependency versions into generated template code (so `spacetime init` can rewrite template manifests without hardcoded versions). After TOML parsing succeeds, it requires the document root to be a table; anything else (an array, a bare value, a mangled file) yields io::ErrorKind::InvalidData with this message, which the .expect() at build.rs:104 turns into a build-script panic.
Source
Thrown at crates/cli/build.rs:449
// We happen to know our own directory structure, so we can just walk the tree to get to the root.
let repo_root = manifest_dir.join("..").join("..");
repo_root.canonicalize().unwrap_or_else(|err| {
panic!(
"Failed to canonicalize repo_root path {}: {err:#?}",
repo_root.display()
)
})
}
fn extract_workspace_metadata(path: &Path) -> io::Result<(String, BTreeMap<String, String>)> {
let content = fs::read_to_string(path)?;
let parsed: Value = content
.parse()
.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
let table = parsed
.as_table()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "workspace manifest is not a table"))?;
let workspace = table
.get("workspace")
.and_then(Value::as_table)
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "workspace section missing"))?;
let edition = workspace
.get("package")
.and_then(Value::as_table)
.and_then(|pkg| pkg.get("edition"))
.and_then(Value::as_str)
.unwrap_or("2021")
.to_string();
let mut versions = BTreeMap::new();
if let Some(deps) = workspace.get("dependencies").and_then(Value::as_table) {
for (name, value) in deps {
let version_opt = match value {View on GitHub (pinned to 6dee26c6ef)
Solutions
- Open the repository-root Cargo.toml and restore a normal manifest shape: top-level keys plus [workspace], [workspace.package] and [workspace.dependencies] sections.
- If a generator rewrote the file, fix the generator to round-trip a table-rooted TOML document and regenerate.
- Smoke-test with `cargo metadata --no-deps` in the repo root; if cargo itself rejects the file, fix the manifest before rebuilding the CLI.
Example fix
# before (root Cargo.toml root is not a table)
[
{ name = "my-workspace" }
]
# after
[workspace]
members = ["crates/*"] Defensive patterns
Strategy: validation
Validate before calling
// Rust: validate the workspace manifest before building the CLI crate
let content = std::fs::read_to_string("Cargo.toml")?;
let parsed: toml::Value = content.parse()?; // fails on invalid TOML
anyhow::ensure!(parsed.is_table(), "root Cargo.toml must be a TOML table"); Try / catch
match extract_workspace_metadata(&workspace_cargo) {
Ok(meta) => meta,
Err(e) if e.kind() == io::ErrorKind::InvalidData => {
// regenerate/restore the root manifest, then fail the build with a clear message
return Err(anyhow!("root Cargo.toml malformed: {e}"));
}
Err(e) => return Err(e.into()),
} Prevention
- Never rewrite the workspace-root manifest with tools that re-serialize the whole document - patch fields in place.
- Add `cargo metadata --no-deps` to CI as a manifest smoke test before building the CLI crate.
- Review root Cargo.toml changes as carefully as lockfile changes; many crates derive versions from it.
When it happens
Trigger: Running cargo build on the SpacetimeDB workspace (anything that compiles the `spacetime` CLI crate) when the root Cargo.toml parses as TOML but its root node is not a table - e.g. the file was truncated, replaced by a non-manifest TOML document, or re-serialized into an array/scalar by tooling.
Common situations: Codegen or scripts that rewrite the root manifest and emit a non-table document; badly resolved merge conflicts leaving the top level malformed; forks whose tooling writes the wrong file to the root path.
Related errors
- workspace section missing
- Missing "version" field in TypeScript bindings package.json
- failed to read {} bytes of commit payload: {}
- failed to read checksum: {e}
- cannot serialize refs without a typespace
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/167fb943cd7e9cfa.
Report an issue: GitHub.