clockworklabs/SpacetimeDB · error · anyhow::Error
database is a required field in publish config
Error message
database is a required field in publish config
What it means
`spacetime dev` reads the project's publish configs (the `[[project.publish]]` entries in spacetime.json) to know which database(s) to stream logs from. Each entry must contain a string-valued `database` field; this error fires during the pre-flight collection of database names (dev.rs:668) when any publish entry lacks `database` or has it as a non-string JSON value.
Solutions
- Open spacetime.json and add `"database": "<your-db-name>"` to every [[project.publish]] entry
- Verify the value is a JSON string, not a number or object
- Validate the file with `spacetime generate`-style config checks or `cat spacetime.json | jq` before running dev
Example fix
// spacetime.json — before
{
"project": {
"publish": [{ "module_path": "server" }]
}
}
// after
{
"project": {
"publish": [{ "module_path": "server", "database": "mydb" }]
}
} Defensive patterns
Strategy: validation
Validate before calling
# jq guard before `spacetime dev`:
jq -e 'all(.project.publish[]?; (.database | type) == "string" and .database != "")' \
spacetime.json >/dev/null || { echo 'every [[project.publish]] needs a string database'; exit 2; } Prevention
- Treat `database` as a required key in every publish entry; add it at authoring time
- Validate spacetime.json with jq in a pre-dev/pre-commit hook
- When adding a second publish target, remember each entry needs its own database field
When it happens
Trigger: A spacetime.json containing a `[[project.publish]]` object without a `database` key, or with `database = 123` / nested object instead of a string. dev mode collects names via get_config_value("database").and_then(as_str) for EVERY publish entry before starting, so one malformed entry aborts the whole run.
Common situations: Hand-editing spacetime.json and dropping the field; templates or generators that emit publish entries with only module_path; migrating from an older config schema where database was implied; copying a multi-project config where one entry was left half-finished.
Related errors
- Missing loaded config directory
- Module bindings path must be a relative path
- `--module-path` cannot be used when `spacetime.json`…
- `--module-path`, `--project-path`, and…
- No database target matches
AI-assisted analysis of clockworklabs/SpacetimeDB@3653d2ed49 (2026-08-20).
Data as JSON: /api/errors/6bdedb515e60b27a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/subcommands/dev.rs:690
if sc.dev.as_ref().and_then(|d| d.run.as_ref()).is_none() {
detect_and_save_client_command(&project_dir, Some(sc.clone()))
} else {
sc.dev.as_ref().and_then(|d| d.run.clone())
}
} else {
// No config file - try to detect and create new
detect_and_save_client_command(&project_dir, None)
};
// Extract database names from publish configs for log streaming
let db_names_for_logging: Vec<String> = publish_configs
.iter()
.map(|config| {
config
.get_config_value("database")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow::anyhow!("database is a required field in publish config"))
.map(|s| s.to_string())
})
.collect::<Result<Vec<_>, _>>()?;
// Use first database for client process
let db_name_for_client = &db_names_for_logging[0];
// Extract watch directories from publish configs
let watch_dirs = extract_watch_dirs(&publish_configs, &spacetimedb_dir, &project_dir);
println!("\n{}", "Starting development mode...".green().bold());
if db_names_for_logging.len() == 1 {
println!("Database: {}", db_names_for_logging[0].cyan());
} else {
println!("Databases: {}", db_names_for_logging.join(", ").cyan());
}
// Announce watch directoriesView on GitHub (pinned to 3653d2ed49)