{"record":{"id":"daedfdff521f9189","repo":"astrid-runtime/astrid","slug":"var-must-be-key-value-got-item","errorCode":null,"errorMessage":"--var must be KEY=VALUE (got {item:?})","messagePattern":"--var must be KEY=VALUE \\(got (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/capsule/install.rs","lineNumber":66,"sourceCode":"    expected: Option<ExpectedCapsule<'a>>,\n    prompt: &'a ManualInstallOptions,\n}\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,","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/capsule/install.rs#L48-L84","documentation":"Raised in ManualInstallOptions::from_cli when a --var item does not contain an '=' separator, so it cannot be split into KEY=VALUE. split_once('=') returns None and the CLI rejects the item, naming the offending value.","triggerScenarios":"Passing --var with a bare key ('DEBUG'), only a value, or using a different separator (':' or spaces) instead of '='.","commonSituations":"Users familiar with --env KEY VALUE style flags omitting the '=', or quoting issues in the shell swallowing the '=' sign.","solutions":["Write each --var item as KEY=VALUE with a literal '='","Quote the whole argument in the shell: --var 'KEY=some value'","Check for empty keys too; the CLI rejects those separately"],"exampleFix":"// before\n--var DEBUG\n// after\n--var DEBUG=true","handlingStrategy":"validation","validationCode":"for item in items {\n    if !item.contains('=') || item.split('=').next().unwrap().is_empty() {\n        eprintln!(\"--var must be KEY=VALUE (got {item:?})\");\n        std::process::exit(2);\n    }\n}","typeGuard":"fn is_key_value(item: &str) -> bool { matches!(item.split_once('='), Some((k, _)) if !k.is_empty()) }","tryCatchPattern":"match ManualInstallOptions::from_cli(yes, approve, &items) { Err(e) => { eprintln!(\"{e:#}\"); std::process::exit(2); }, Ok(opts) => opts }","preventionTips":["Always write --var KEY=VALUE with a literal '='","Quote arguments containing spaces or special characters in the shell","Deduplicate keys before passing multiple --var flags"],"tags":["cli","arguments","validation"],"backgroundTag":"invalid-argument-format","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"}