{"record":{"id":"6bdedb515e60b27a","repo":"clockworklabs/SpacetimeDB","slug":"database-is-a-required-field-in-publish-config","errorCode":null,"errorMessage":"database is a required field in publish config","messagePattern":"database is a required field in publish config","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/cli/src/subcommands/dev.rs","lineNumber":690,"sourceCode":"\n        if sc.dev.as_ref().and_then(|d| d.run.as_ref()).is_none() {\n            detect_and_save_client_command(&project_dir, Some(sc.clone()))\n        } else {\n            sc.dev.as_ref().and_then(|d| d.run.clone())\n        }\n    } else {\n        // No config file - try to detect and create new\n        detect_and_save_client_command(&project_dir, None)\n    };\n\n    // Extract database names from publish configs for log streaming\n    let db_names_for_logging: Vec<String> = publish_configs\n        .iter()\n        .map(|config| {\n            config\n                .get_config_value(\"database\")\n                .and_then(|v| v.as_str())\n                .ok_or_else(|| anyhow::anyhow!(\"database is a required field in publish config\"))\n                .map(|s| s.to_string())\n        })\n        .collect::<Result<Vec<_>, _>>()?;\n\n    // Use first database for client process\n    let db_name_for_client = &db_names_for_logging[0];\n\n    // Extract watch directories from publish configs\n    let watch_dirs = extract_watch_dirs(&publish_configs, &spacetimedb_dir, &project_dir);\n\n    println!(\"\\n{}\", \"Starting development mode...\".green().bold());\n    if db_names_for_logging.len() == 1 {\n        println!(\"Database: {}\", db_names_for_logging[0].cyan());\n    } else {\n        println!(\"Databases: {}\", db_names_for_logging.join(\", \").cyan());\n    }\n\n    // Announce watch directories","sourceCodeStart":672,"sourceCodeEnd":708,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/3653d2ed498fddbd83b7062aa6bf8970e18635ec/crates/cli/src/subcommands/dev.rs#L672-L708","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// spacetime.json — before\n{\n  \"project\": {\n    \"publish\": [{ \"module_path\": \"server\" }]\n  }\n}\n// after\n{\n  \"project\": {\n    \"publish\": [{ \"module_path\": \"server\", \"database\": \"mydb\" }]\n  }\n}","handlingStrategy":"validation","validationCode":"# jq guard before `spacetime dev`:\njq -e 'all(.project.publish[]?; (.database | type) == \"string\" and .database != \"\")' \\\n  spacetime.json >/dev/null || { echo 'every [[project.publish]] needs a string database'; exit 2; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["cli","dev","config","spacetime-json","validation"],"backgroundTag":"missing-config-field","analyzedSha":"3653d2ed498fddbd83b7062aa6bf8970e18635ec","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}