affaan-m/ECC · error · anyhow::Error
{label} must use key=value form: {value}
Error message
{label} must use key=value form: {value} What it means
Thrown by parse_key_value_pairs (used for template vars, graph metadata, observation details) when one of the provided string entries has no '=' delimiter at all. The parser requires every entry to be in key=value form; an entry lacking '=' cannot be split into a key and value and is rejected.
Source
Thrown at ecc2/src/main.rs:8593
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 01e15490f0)
Solutions
- Rewrite the offending entry as key=value, e.g. '--var component=billing' instead of '--var component'.
- If scripting, construct args with format!("{key}={value}") rather than space-separated tokens.
- Quote each entry so the shell does not split on '=' or whitespace.
- Re-read the error: it includes the exact value that failed, so fix that one entry.
Example fix
# before ecc2 run --var component --var area=oauth # after ecc2 run --var component=billing --var area=oauth
Defensive patterns
Strategy: validation
Validate before calling
fn is_key_value(entry: &str) -> bool {
entry.split_once('=').is_some()
}
// validate CLI args up front
for v in &vars {
if !is_key_value(v) {
return Err(anyhow!("{v} must be key=value"));
}
} Prevention
- Always pass '--flag key=value'.
- When scripting, build entries with format!("{k}={v}").
- Quote each entry to protect '=' from the shell.
When it happens
Trigger: Passing a CLI flag like --var component (no '=') or --metadata lang (no '='), or a positional value that omits the delimiter. The label in the message identifies which flag (e.g. 'template vars', 'graph metadata', 'graph observation details').
Common situations: User forgets the '=value' part; shell quoting strips the '='; a script builds args by joining key and value with a space instead of '='; copy-pasting from docs that show the key only.
Related errors
- {label} must use non-empty key=value form: {value}
- Legacy workspace source must be a directory: {}
- Unknown argument: ${arg}
- Unknown argument: ${arg}
- --timeout-ms must be a positive number
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/d5fe63abc74e5caa.
Report an issue: GitHub.