astrid-runtime/astrid · error

--var must be KEY=VALUE (got {item:?})

Error message

--var must be KEY=VALUE (got {item:?})

What it means

`validate_values` parses each `--var` CLI item by splitting on the first `=` to produce a KEY=VALUE pair for daemon env injection. It throws when an item contains no `=` at all, so no key/value pair can be extracted.

Source

Thrown at crates/astrid-cli/src/commands/capsule/install_daemon.rs:415

        return astrid_capsule::discovery::load_manifest(&path.join("Capsule.toml"))
            .map_err(Into::into);
    }
    if path.is_file() {
        return astrid_capsule_install::read_archive_manifest(path)
            .with_context(|| format!("read Capsule.toml from {}", path.display()));
    }
    bail!("source path does not exist: {source}")
}

fn validate_values(
    manifest: &CapsuleManifest,
    items: &[String],
) -> anyhow::Result<Vec<DaemonEnvValue>> {
    let mut parsed = HashMap::new();
    for item in items {
        let (key, value) = item
            .split_once('=')
            .ok_or_else(|| anyhow::anyhow!("--var must be KEY=VALUE (got {item:?})"))?;
        if key.is_empty() || key.contains('\0') || key.contains(':') {
            bail!("--var has an invalid key (got {key:?})");
        }
        if parsed.insert(key.to_owned(), value.to_owned()).is_some() {
            bail!("--var '{key}' was supplied more than once");
        }
    }

    let mut values = Vec::with_capacity(parsed.len());
    for (key, value) in parsed {
        let definition = manifest.env.get(&key).ok_or_else(|| {
            anyhow::anyhow!(
                "--var names no [env] field in {}: {key}",
                manifest.package.name
            )
        })?;
        let kind = if definition.env_type.eq_ignore_ascii_case("secret") {
            if value.len() > 64 * 1024 {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Supply the full KEY=VALUE form: `--var KEY=value`
  2. Quote the argument in your shell so `=` and spaces survive: `--var "KEY=some value"`
  3. Remember a separate `--var` flag per pair, not space-separated pairs

Example fix

// before
mytool --var LOG_LEVEL
// after
mytool --var LOG_LEVEL=debug
Defensive patterns

Strategy: validation

Validate before calling

fn valid_var_items(items: &[String]) -> bool {
    items.iter().all(|i| {
        match i.split_once('=') {
            Some((k, _)) => !k.is_empty() && !k.contains('\0') && !k.contains(':'),
            None => false,
        }
    })
}

Try / catch

match result {
    Err(e) if e.to_string().starts_with("--var must be KEY=VALUE") => {
        eprintln!("Fix the --var argument: each must be KEY=VALUE, quoted if it contains spaces.");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Passing `--var KEY` (missing `=VALUE`), `--var "KEY="`-less forms like `--var "FLAG"`, or values that got shell-mangled so the `=` was lost (e.g. unquoted spaces splitting the argument).

Common situations: Forgetting the value in shell history/editing; quoting mistakes where `--var KEY=VALUE` becomes two argv entries; copy-pasting env var names without values; writing `--var KEY:VALUE` (colon instead of equals).

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


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/7eecc00575c80496. Report an issue: GitHub.