{"record":{"id":"0b50ce0b4cce8f76","repo":"clockworklabs/SpacetimeDB","slug":"replace-env-cannot-be-combined-with-unset-env","errorCode":null,"errorMessage":"--replace-env cannot be combined with --unset-env","messagePattern":"--replace-env cannot be combined with --unset-env","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/subcommands/publish.rs","lineNumber":383,"sourceCode":"            only: args.get_flag(\"env_only\"),\n            remove: args\n                .get_many::<String>(\"unset_env\")\n                .map(|keys| keys.cloned().collect())\n                .unwrap_or_default(),\n            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,","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/cli/src/subcommands/publish.rs#L365-L401","documentation":"The CLI's `validate_values` (called from `publication_body` in the publish flow) rejects an EnvironmentOptions where `--replace-env` is set while `--unset-env` is non-empty. Replacing all environment values and simultaneously removing individual keys is contradictory: after a full replace there is nothing left to unset, and the two flags would fight over the final value set. The check uses `ensure!` so it fires before any network request is made.","triggerScenarios":"Running `spacetime publish` with both `--replace-env` and one or more `--unset-env KEY` flags; programmatically constructing EnvironmentOptions with `replace=true` and a non-empty `remove` BTreeMap and passing it to publication_body/execute_publish_configs.","commonSituations":"Developers cleaning up environment configuration who want to start fresh (`--replace-env`) but also clear one specific leftover key with `--unset-env`; scripts that append flags conditionally and end up passing both.","solutions":["Use only `--replace-env` (supply the full final set of values; omitted keys are effectively unset).","Alternatively drop `--replace-env` and use `--unset-env KEY` to remove just the specific keys.","If both behaviors are needed across steps, run two publish calls: one to unset keys, one to replace values."],"exampleFix":"// before\nspacetime publish --replace-env --unset-env MY_SECRET -d mydb\n// after (replace env; omit the key instead of unsetting it)\nspacetime publish --replace-env OTHER=value -d mydb","handlingStrategy":"validation","validationCode":"// bash pre-check before invoking publish\nif grep -q -- '--replace-env' args.txt && grep -q -- '--unset-env' args.txt; then\n  echo \"Refusing: --replace-env and --unset-env are mutually exclusive\"; exit 1;\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick one strategy per publish: full replace OR targeted unset, never both.","Build CLI flag lists programmatically with an assertion that the two flags never co-occur.","Remember --replace-env already drops omitted keys; you don't need --unset-env with it."],"tags":["cli","environment","flag-conflict","validation"],"backgroundTag":"mutually-exclusive-flags","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"}