astrid-runtime/astrid · error
invalid value for {capsule_id}.{key}: expected one of {}, go
Error message
invalid value for {capsule_id}.{key}: expected one of {}, got {value:?} What it means
Raised by `collect_install_env_fields` in the capsule installer when a value supplied for a declared `[env]` field fails the field's enum check. Capsule definitions can declare `enum_values` for an env field; before staging the configuration for the daemon-owned install transaction, every value (from `--var`, headless env vars, defaults, or interactive prompt) must exactly match one of the declared options. The library throws this so invalid capsule configuration never reaches the daemon install hook.
Source
Thrown at crates/astrid-cli/src/commands/capsule/install_prompts.rs:195
std::env::var(&env_key)
.ok()
.or_else(|| def.default.as_ref().map(json_value_string))
.ok_or_else(|| {
anyhow::anyhow!(
"required value is missing for {capsule_id}.{key} \
(use --var {key}=… or set {env_key})"
)
})?
} else {
if !prompted {
eprintln!("\nThis capsule requires configuration:");
prompted = true;
}
prompt_single_field(&key, def, &collected)
};
if !def.enum_values.is_empty() && !def.enum_values.iter().any(|item| item == &value) {
anyhow::bail!(
"invalid value for {capsule_id}.{key}: expected one of {}, got {value:?}",
def.enum_values.join(", ")
);
}
if def.env_type != "secret" && !value.is_empty() {
super::local_egress::maybe_prompt_local_egress(capsule_id, &value, config_path);
}
collected.insert(key.clone(), serde_json::Value::String(value.clone()));
values.push(format!("{key}={value}"));
}
if prompted {
eprintln!(" Configuration will be applied by the daemon.\n");
}
Ok(values)
}
/// Prompt the user for missing environment-variable values defined in `[env]`.View on GitHub (pinned to affd8760f4)
Solutions
- Read the list of allowed values from the error message ('expected one of ...') and pass an exact match, e.g. `--var <key>=<allowed-value>`.
- Check the capsule's `[env]` definition for the field's `enum_values`/options and its casing; matching is exact string equality.
- If the value used to be valid, the capsule manifest changed — update your scripts/CI to the new allowed set or pin the older capsule version.
- If you believe the value should be legal, ask the capsule author to add it to the field's enum_values and reinstall.
Example fix
// before astrid capsule install my-capsule --var log-level=VERBOSE // error: invalid value for my-capsule.log-level: expected one of debug, info, warn, error, got "VERBOSE" // after astrid capsule install my-capsule --var log-level=error
Defensive patterns
Strategy: validation
Validate before calling
let allowed = env_def.enum_values;
if !allowed.is_empty() && !allowed.iter().any(|v| v == value) {
eprintln!("{key} must be one of: {}", allowed.join(", "));
std::process::exit(2);
} Type guard
fn is_valid_enum_value(value: &str, def: &EnvDef) -> bool {
def.enum_values.is_empty() || def.enum_values.iter().any(|item| item == value)
} Try / catch
match collect_install_env_fields(...) {
Ok(values) => install(values),
Err(e) if e.to_string().contains("invalid value for") => {
eprintln!("{e:#}\nFix with: --var <key>=<allowed-value>");
std::process::exit(2);
},
Err(e) => return Err(e),
} Prevention
- Echo the field's allowed options before prompting or scripting values.
- Keep `--var` values for enum fields in checked-in scripts so casing/typos are fixed once.
- When a capsule updates, diff its [env] enum_values against the values your CI supplies.
- Use tab-completion or interactive prompting instead of hand-typing enum values.
When it happens
Trigger: Running `astrid capsule install` for a capsule whose EnvDef declares `enum_values`, while the resolved value for that key (via `--var key=value`, the headless env variable, the field default, or a prompted answer) is not an exact string match of any declared enum value. Also triggered by tests install_collection_replaces_explicit_existing_and_preserves_other_existing and install_collection_rejects_undeclared_and_invalid_enum_values.
Common situations: Typo in a `--var` value (e.g. `log-level=INFO` when options are `debug,info,warn,error`); wrong casing since matching is case-sensitive; capsule manifest was updated to a new set of allowed options while the user reuses an old value; an old default baked into CI env vars.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- --retain-entries must be at least 1
- --retain-bytes must be greater than 0
- --var has an empty key (got {item:?})
- --var '{key}' was supplied more than once
- --var has an invalid key (got {key:?})
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/ad0adfd72f64492d.
Report an issue: GitHub.