clockworklabs/SpacetimeDB · error
Environment key is both supplied and removed
Error message
Environment key {key:?} is both supplied and removed What it means
`validate_values` iterates the `--unset-env` keys and rejects any key that also appears in the supplied values map (from `--env KEY=VALUE` or shell lookups). Supplying and removing the same key in one publication is ambiguous — the CLI refuses to guess which wins.
Solutions
- Remove the key from one of the two lists — keep `--env KEY=value` if you want the new value, or `--unset-env KEY` if you want it gone.
- Audit the resolved values map (including shell-derived values) before publishing to check for overlap with `remove`.
- If you intended to change a key, just supply `--env KEY=newvalue` without unsetting it.
Example fix
// before spacetime publish --env FOO=bar --unset-env FOO -d mydb // after spacetime publish --env FOO=newbar -d mydb
Defensive patterns
Strategy: validation
Validate before calling
// rust: caller-side pre-check mirroring the CLI rule
let overlap: Vec<_> = options.remove.iter().filter(|k| values.contains_key(*k)).collect();
if !overlap.is_empty() {
panic!("keys both supplied and unset: {overlap:?}");
} Prevention
- Keep supplied keys and removed keys in separate, reviewed sources (config file vs cleanup list).
- Before publishing, diff the resolved values map against the unset list.
- Prefer supplying a new value over unset+supply pairs when changing a key.
When it happens
Trigger: `spacetime publish --env FOO=bar --unset-env FOO`; supplying FOO via shell environment while also listing FOO in `--unset-env`; programmatic EnvironmentOptions where `values` contains a key present in `remove`.
Common situations: Scripts built from lists of keys where a key accidentally appears in both an override list and a removal list; stale flag files where a key was previously removed but a new `--env` line was added for it.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Invalid environment key name
- --replace-env cannot be combined with --unset-env
- Cannot read environment schema: HTTP
- database is a required field in publish config
- Either --out-dir or --uproject-dir is required
AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-09-20).
Data as JSON: /api/errors/705bb2220548152e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/subcommands/publish.rs:388
replace: args.get_flag("replace_env"),
};
ensure!(
options.remove.len() <= spacetimedb_lib::environment::MAX_ENV_VARS,
"Too many environment removals"
);
for key in &options.remove {
spacetimedb_lib::environment::validate_key(key)?;
}
Ok(options)
}
fn validate_values(&self, values: &std::collections::BTreeMap<String, String>) -> anyhow::Result<()> {
ensure!(
!self.replace || self.remove.is_empty(),
"--replace-env cannot be combined with --unset-env"
);
for key in &self.remove {
ensure!(
!values.contains_key(key),
"Environment key {key:?} is both supplied and removed"
);
}
Ok(())
}
}
fn publication_body(
module: &spacetimedb_schema::def::ModuleDef,
bytes: Vec<u8>,
environment: std::collections::BTreeMap<String, String>,
options: &EnvironmentOptions,
) -> anyhow::Result<(&'static str, Vec<u8>)> {
options.validate_values(&environment)?;
if module.environment_declared() || !environment.is_empty() || !options.remove.is_empty() || options.replace {
let body = spacetimedb_client_api_messages::publish::PublishRequest {
module: Some(bytes),View on GitHub (pinned to eddf9f5014)