astrid-runtime/astrid · error

required variable '{var_name}' has no value (no --var {var_n

Error message

required variable '{var_name}' has no value (no --var {var_name}=…, no {env_key}, no default)

What it means

collect_variables_headless resolves each required template variable from three sources in order: --var CLI values, the mapped environment variable, then the variable definition's default. When all three are absent for a required variable, this error names the variable, the --var flag, the expected env key, and the missing default. It exists so headless runs fail deterministically instead of prompting.

Source

Thrown at crates/astrid-cli/src/commands/init.rs:543

    variables: &HashMap<String, super::distro::manifest::VariableDef>,
    needed_vars: &std::collections::HashSet<String>,
    cli_vars: &HashMap<String, String>,
    env_lookup: impl Fn(&str) -> Option<String>,
) -> anyhow::Result<HashMap<String, String>> {
    let mut vars = HashMap::new();
    let mut sorted: Vec<&str> = needed_vars.iter().map(String::as_str).collect();
    sorted.sort_unstable();

    for var_name in sorted {
        let env_key = format!("ASTRID_VAR_{}", var_name.to_uppercase());
        let var_def = variables.get(var_name);
        let value = cli_vars
            .get(var_name)
            .cloned()
            .or_else(|| env_lookup(&env_key))
            .or_else(|| var_def.and_then(|d| d.default.clone()))
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "required variable '{var_name}' has no value \
                     (no --var {var_name}=…, no {env_key}, no default)"
                )
            })?;

        let is_secret = var_def.is_some_and(|d| d.secret);
        if is_secret {
            tracing::debug!(var = %var_name, "resolved distro variable [secret]");
        } else {
            tracing::debug!(var = %var_name, value = %value, "resolved distro variable");
        }

        vars.insert(var_name.to_string(), value);
    }

    Ok(vars)
}

View on GitHub (pinned to affd8760f4)

Solutions

  1. Pass the value explicitly: astrid init --var <name>=<value>
  2. Export the expected environment variable shown in the error before running init
  3. Provide a default for the variable in the template definition
  4. If the variable should be optional, mark it as such in the template

Example fix

// before
astrid init --group web
// after
astrid init --group web --var project_name=my-app
// or
export PROJECT_NAME=my-app && astrid init --group web
Defensive patterns

Strategy: validation

Validate before calling

fn required_vars_missing<'a>(
    template: &'a Template,
    cli: &HashMap<String, String>,
) -> Vec<&'a str> {
    template.variables.iter()
        .filter(|v| v.required)
        .filter(|v| {
            cli.contains_key(&v.name)
                || std::env::var_os(&v.env_key).is_some()
                || v.default.is_some()
        }
        .then_some(()) .is_none())
        .map(|v| v.name.as_str())
        .collect()
}

Try / catch

match collect_variables(&template, &cli_vars) {
    Err(e) if e.to_string().contains("has no value") => {
        eprintln!("{e}\nhint: pass --var or export the env var listed above");
        std::process::exit(2);
    }
    other => other?,
}

Prevention

When it happens

Trigger: Running `astrid init` headless (non-TTY/CI) where a template declares a required variable with no default, and the caller supplies neither --var <name>=… nor the corresponding environment variable.

Common situations: CI pipelines that used to prompt interactively now failing headless; secrets not exported in the CI environment; renamed env keys; templates gaining a new required variable after an update.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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