Summary
spacetime publish reads the database name from spacetime.json when no positional argument is given, but adding -c/--delete-data defeats that fallback and the parser errors out demanding <name|identity>.
Reproducer
spacetime.json:
{
"server": "local",
"database": "space-transactions",
"module-path": "./module"
}
| Invocation |
Result |
spacetime publish |
✅ uses space-transactions from config |
spacetime publish --yes |
✅ uses config name |
spacetime publish -c=always |
❌ `error: required arguments not provided: <name |
spacetime publish -c=always --yes |
❌ same error |
spacetime publish -c=always space-transactions |
✅ works |
--yes alone is fine. The failure is exclusively triggered by -c/--delete-data.
Exact error:
$ spacetime publish -c=always
error: the following required arguments were not provided:
<name|identity>
Usage: spacetime publish --delete-data[=<clear-database>] <name|identity>
Tested against spacetimedb tool version 2.4.1; spacetimedb-lib version 2.4.1.
Cause
In crates/cli/src/subcommands/publish.rs the clear_database arg carries a clap-level .requires(\"name|identity\"):
.arg(
common_args::clear_database()
.requires(\"name|identity\")
)
That constraint fires during clap parsing — before the config-driven name fallback runs. The rest of the file already understands the name can come from config:
publish.rs:87 — Key::new(\"database\").from_clap(\"name|identity\").required() marks the name as required at the schema layer (satisfiable by clap or config).
publish.rs:484-485 — name_or_identity is read from the merged CommandConfig (clap + spacetime.json).
So bare spacetime publish works because the schema-layer check sees the config value. -c=always short-circuits that by failing clap parsing first.
The .requires predates the config-driven Key schema infrastructure — git log -L 195,197:crates/cli/src/subcommands/publish.rs traces it back through PR #3601 (move to common_args::clear_database()) and PR #1880 (name|address → name|identity rename). The config-fallback layer was added later without revisiting it.
Suggested fix
Drop the clap-level .requires(\"name|identity\"). The schema/config merge already enforces "must know which database" — validate_name_and_parent at publish.rs:531 returns an error cleanly if name_or_identity is still None after the merge. Data destruction is gated by the confirmation prompt regardless, so the constraint isn't load-bearing for safety.
Summary
spacetime publishreads the database name fromspacetime.jsonwhen no positional argument is given, but adding-c/--delete-datadefeats that fallback and the parser errors out demanding<name|identity>.Reproducer
spacetime.json:{ "server": "local", "database": "space-transactions", "module-path": "./module" }spacetime publishspace-transactionsfrom configspacetime publish --yesspacetime publish -c=alwaysspacetime publish -c=always --yesspacetime publish -c=always space-transactions--yesalone is fine. The failure is exclusively triggered by-c/--delete-data.Exact error:
Tested against
spacetimedb tool version 2.4.1; spacetimedb-lib version 2.4.1.Cause
In
crates/cli/src/subcommands/publish.rstheclear_databasearg carries a clap-level.requires(\"name|identity\"):That constraint fires during clap parsing — before the config-driven name fallback runs. The rest of the file already understands the name can come from config:
publish.rs:87—Key::new(\"database\").from_clap(\"name|identity\").required()marks the name as required at the schema layer (satisfiable by clap or config).publish.rs:484-485—name_or_identityis read from the mergedCommandConfig(clap +spacetime.json).So bare
spacetime publishworks because the schema-layer check sees the config value.-c=alwaysshort-circuits that by failing clap parsing first.The
.requirespredates the config-drivenKeyschema infrastructure —git log -L 195,197:crates/cli/src/subcommands/publish.rstraces it back through PR #3601 (move tocommon_args::clear_database()) and PR #1880 (name|address→name|identityrename). The config-fallback layer was added later without revisiting it.Suggested fix
Drop the clap-level
.requires(\"name|identity\"). The schema/config merge already enforces "must know which database" —validate_name_and_parentatpublish.rs:531returns an error cleanly ifname_or_identityis stillNoneafter the merge. Data destruction is gated by the confirmation prompt regardless, so the constraint isn't load-bearing for safety.