{"record":{"id":"d5fe63abc74e5caa","repo":"affaan-m/ECC","slug":"label-must-use-key-value-form-value","errorCode":null,"errorMessage":"{label} must use key=value form: {value}","messagePattern":"(.+?) must use key=value form: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ecc2/src/main.rs","lineNumber":8592,"sourceCode":"        to_id,\n        &comms::MessageType::TaskHandoff {\n            task: from_session.task,\n            context,\n            priority: comms::TaskPriority::Normal,\n        },\n    )\n}\n\nfn parse_template_vars(values: &[String]) -> Result<BTreeMap<String, String>> {\n    parse_key_value_pairs(values, \"template vars\")\n}\n\nfn parse_key_value_pairs(values: &[String], label: &str) -> Result<BTreeMap<String, String>> {\n    let mut vars = BTreeMap::new();\n    for value in values {\n        let (key, raw_value) = value\n            .split_once('=')\n            .ok_or_else(|| anyhow::anyhow!(\"{label} must use key=value form: {value}\"))?;\n        let key = key.trim();\n        let raw_value = raw_value.trim();\n        if key.is_empty() || raw_value.is_empty() {\n            anyhow::bail!(\"{label} must use non-empty key=value form: {value}\");\n        }\n        vars.insert(key.to_string(), raw_value.to_string());\n    }\n    Ok(vars)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::config::Config;\n    use crate::session::store::StateStore;\n    use crate::session::{Session, SessionMetrics, SessionState};\n    use chrono::{Duration, Utc};\n    use std::fs;","sourceCodeStart":8574,"sourceCodeEnd":8610,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/main.rs#L8574-L8610","documentation":"parse_key_value_pairs expects each CLI value in KEY=VALUE form (e.g. VAR=x). When a supplied value lacks an '=' separator, it fails with '{label} must use key=value form: {value}'. A related bail also rejects empty keys or values.","triggerScenarios":"Passing flags like --env PATH or --env '=x' / 'KEY=' to options built on parse_key_value_pairs (env vars, headers, labels).","commonSituations":"Quoting mistakes in the shell that drop the '=', forgetting the value entirely, or using a shell that splits on spaces so only the key survives.","solutions":["Quote the whole pair in your shell: --env 'KEY=value'.","Ensure there is exactly one '=' separating a non-empty key and a non-empty value.","If the value itself contains '=', that's fine (split_once takes the first '='), but the key portion before it must be non-empty.","Check with `echo` or shell tracing that the argument reached the program intact."],"exampleFix":"// before\nmyapp run --env PATH --env DEBUG=1\n// after\nmyapp run --env \"PATH=/usr/bin\" --env \"DEBUG=1\"","handlingStrategy":"validation","validationCode":"fn is_key_value(s: &str) -> bool {\n    match s.split_once('=') {\n        Some((k, v)) => !k.trim().is_empty() && !v.trim().is_empty(),\n        None => false,\n    }\n}\n// validate each --env arg before invoking the command","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Quote KEY=VALUE arguments in shells to survive space splitting","Never pass bare keys without '='","Remember values may contain '=' (only the first separates)","Add shell completion/linting for pair-style flags"],"tags":["cli","parsing","key-value"],"backgroundTag":"invalid-argument-format","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}