affaan-m/ECC · error
must use key=value form
Error message
{label} must use key=value form: {value} What it means
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.
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.
Example fix
// before myapp run --env PATH --env DEBUG=1 // after myapp run --env "PATH=/usr/bin" --env "DEBUG=1"
Defensive patterns
Strategy: validation
Validate before calling
fn is_key_value(s: &str) -> bool {
match s.split_once('=') {
Some((k, v)) => !k.trim().is_empty() && !v.trim().is_empty(),
None => false,
}
}
// validate each --env arg before invoking the command Prevention
- 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
When it happens
Trigger: Passing flags like --env PATH or --env '=x' / 'KEY=' to options built on parse_key_value_pairs (env vars, headers, labels).
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- requires a value
- requires a value
- gh returned invalid JSON
- Missing value for --install-dir.
- Missing value for .
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/d5fe63abc74e5caa.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/main.rs:8592
to_id,
&comms::MessageType::TaskHandoff {
task: from_session.task,
context,
priority: comms::TaskPriority::Normal,
},
)
}
fn parse_template_vars(values: &[String]) -> Result<BTreeMap<String, String>> {
parse_key_value_pairs(values, "template vars")
}
fn parse_key_value_pairs(values: &[String], label: &str) -> Result<BTreeMap<String, String>> {
let mut vars = BTreeMap::new();
for value in values {
let (key, raw_value) = value
.split_once('=')
.ok_or_else(|| anyhow::anyhow!("{label} must use key=value form: {value}"))?;
let key = key.trim();
let raw_value = raw_value.trim();
if key.is_empty() || raw_value.is_empty() {
anyhow::bail!("{label} must use non-empty key=value form: {value}");
}
vars.insert(key.to_string(), raw_value.to_string());
}
Ok(vars)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::Config;
use crate::session::store::StateStore;
use crate::session::{Session, SessionMetrics, SessionState};
use chrono::{Duration, Utc};
use std::fs;View on GitHub (pinned to 8321021c54)