{"record":{"id":"705bb2220548152e","repo":"clockworklabs/SpacetimeDB","slug":"environment-key-key-is-both-supplied-and-removed","errorCode":null,"errorMessage":"Environment key {key:?} is both supplied and removed","messagePattern":"Environment key (.+?) is both supplied and removed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/subcommands/publish.rs","lineNumber":388,"sourceCode":"            replace: args.get_flag(\"replace_env\"),\n        };\n        ensure!(\n            options.remove.len() <= spacetimedb_lib::environment::MAX_ENV_VARS,\n            \"Too many environment removals\"\n        );\n        for key in &options.remove {\n            spacetimedb_lib::environment::validate_key(key)?;\n        }\n        Ok(options)\n    }\n\n    fn validate_values(&self, values: &std::collections::BTreeMap<String, String>) -> anyhow::Result<()> {\n        ensure!(\n            !self.replace || self.remove.is_empty(),\n            \"--replace-env cannot be combined with --unset-env\"\n        );\n        for key in &self.remove {\n            ensure!(\n                !values.contains_key(key),\n                \"Environment key {key:?} is both supplied and removed\"\n            );\n        }\n        Ok(())\n    }\n}\n\nfn publication_body(\n    module: &spacetimedb_schema::def::ModuleDef,\n    bytes: Vec<u8>,\n    environment: std::collections::BTreeMap<String, String>,\n    options: &EnvironmentOptions,\n) -> anyhow::Result<(&'static str, Vec<u8>)> {\n    options.validate_values(&environment)?;\n    if module.environment_declared() || !environment.is_empty() || !options.remove.is_empty() || options.replace {\n        let body = spacetimedb_client_api_messages::publish::PublishRequest {\n            module: Some(bytes),","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/cli/src/subcommands/publish.rs#L370-L406","documentation":"`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.","triggerScenarios":"`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`.","commonSituations":"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.","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."],"exampleFix":"// before\nspacetime publish --env FOO=bar --unset-env FOO -d mydb\n// after\nspacetime publish --env FOO=newbar -d mydb","handlingStrategy":"validation","validationCode":"// rust: caller-side pre-check mirroring the CLI rule\nlet overlap: Vec<_> = options.remove.iter().filter(|k| values.contains_key(*k)).collect();\nif !overlap.is_empty() {\n    panic!(\"keys both supplied and unset: {overlap:?}\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["cli","environment","conflicting-input","validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"eddf9f5014579a50d4b67630e28b6e15cad9c4af","analyzedAt":"2026-09-20T12:15:59.611Z","contentChangedAt":"2026-09-20T12:15:59.611Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}