{"record":{"id":"c25a437db3a8adc0","repo":"astrid-runtime/astrid","slug":"var-has-an-empty-key-got-item","errorCode":null,"errorMessage":"--var has an empty key (got {item:?})","messagePattern":"--var has an empty key \\(got (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/capsule/install.rs","lineNumber":68,"sourceCode":"}\n\n/// Operator input policy for a manual capsule install.\n#[derive(Debug, Clone, Default)]\npub(super) struct ManualInstallOptions {\n    pub(super) yes: bool,\n    pub(super) approve_untrusted: bool,\n    pub(super) vars: HashMap<String, String>,\n}\n\nimpl ManualInstallOptions {\n    fn from_cli(yes: bool, approve_untrusted: bool, items: &[String]) -> anyhow::Result<Self> {\n        let mut vars = HashMap::new();\n        for item in items {\n            let (key, value) = item\n                .split_once('=')\n                .ok_or_else(|| anyhow::anyhow!(\"--var must be KEY=VALUE (got {item:?})\"))?;\n            if key.is_empty() {\n                bail!(\"--var has an empty key (got {item:?})\");\n            }\n            if vars.insert(key.to_string(), value.to_string()).is_some() {\n                bail!(\"--var '{key}' was supplied more than once\");\n            }\n        }\n        Ok(Self {\n            yes,\n            approve_untrusted,\n            vars,\n        })\n    }\n}\n\n#[derive(Clone, Copy)]\npub(crate) struct OfflineCapsuleProvenance<'a> {\n    pub(crate) original_source: &'a str,\n    pub(crate) resolved_ref: Option<&'a str>,\n    pub(crate) signer: Option<&'a str>,","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/capsule/install.rs#L50-L86","documentation":"`from_cli` parses each `--var KEY=VALUE` item with `split_once('=')`. After splitting, if the key part is empty (e.g. `--var =value` or `--var =`), it bails with this message including the offending item in debug form. It enforces that every variable override has a non-empty key.","triggerScenarios":"Running `astrid capsule install` with `--var` whose value has no characters before `=`: `--var =foo`, `--var =`, or a shell-quoting accident that drops the key (e.g. `--var \"$EMPTY\"=x`).","commonSituations":"Scripted installs where a variable holding the key is empty; copy-pasted CLI examples with the key lost; shell expansions interpolating to `=value`.","solutions":["Supply the variable as `KEY=VALUE` with a non-empty KEY: `--var MY_VAR=value`.","Check shell quoting/expansions — an empty variable before `=` yields an empty key.","Review the printed `{item:?}` to see the exact malformed argument the CLI received.","Remove the offending `--var` flag if it was added by mistake."],"exampleFix":"// before\n--var =value\n// after\n--var MY_KEY=value","handlingStrategy":"validation","validationCode":"fn validate_var(item: &str) -> Result<(), String> {\n    match item.split_once('=') {\n        Some((k, _)) if !k.is_empty() => Ok(()),\n        _ => Err(format!(\"--var must be non-empty KEY=VALUE, got {item:?}\")),\n    }\n}\n// validate every --var before invoking the CLI","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"empty key\") =>\n        eprintln!(\"Fix your --var flags: every entry needs KEY=VALUE with a non-empty KEY.\"),\n    other => other.expect(\"install failed\"),\n}","preventionTips":["Always write --var as KEY=VALUE with a non-empty key.","In scripts, check that key variables are non-empty before building the command.","Quote args carefully so shell expansion cannot drop the key.","Read the echoed {item:?} to spot the exact malformed flag."],"tags":["cli","validation","arguments"],"backgroundTag":"empty-required-field","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}