astrid-runtime/astrid · error · anyhow::Error

ASTRID_ENFORCED_DISTRO must contain a valid UTF-8 distro…

Error message

ASTRID_ENFORCED_DISTRO must contain a valid UTF-8 distro source

What it means

Validation guard in cargo_config_includes: a Cargo config [include] entry used the table form but its 'path' key is missing or not a string, so the include cannot be resolved while loading build content.

Solutions

  1. Unset and re-export ASTRID_ENFORCED_DISTRO with plain ASCII/UTF-8 content
  2. Fix the embedding launcher to write valid UTF-8 into the variable
  3. Check shell profiles/CI config for stray binary characters
  4. echo -n "$ASTRID_ENFORCED_DISTRO" | iconv -f utf-8 -t utf-8 to verify validity

Example fix

// before
export ASTRID_ENFORCED_DISTRO=$'\xff@owner/repo'
// after
export ASTRID_ENFORCED_DISTRO='@owner/repo'
Defensive patterns

Strategy: validation

Validate before calling

match std::env::var_os("ASTRID_ENFORCED_DISTRO") {
    Some(v) if v.to_str().is_none() => eprintln!("ASTRID_ENFORCED_DISTRO is not valid UTF-8"),
    _ => {}
}

Type guard

fn enforced_distro_valid() -> bool {
    std::env::var_os("ASTRID_ENFORCED_DISTRO")
        .map(|v| v.to_string().ok().map(|s| !s.is_empty()).unwrap_or(false))
        .unwrap_or(true)
}

Try / catch

match resolve_init_distro(requested) {
    Err(e) if e.to_string().contains("valid UTF-8") => eprintln!("re-export ASTRID_ENFORCED_DISTRO with UTF-8 content"),
    other => other?,
}

Prevention

When it happens

Trigger: resolve_init_distro_with calls enforced.into_string() on the OsString from the environment and it contains non-UTF-8 bytes (e.g. invalid encoding injected by a launcher or shell).

Common situations: A launcher writing the env var from non-UTF-8 binary data; locale/encoding mismatches on exotic systems; corrupted shell profiles exporting broken bytes.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


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

Appendix: source

Thrown at crates/astrid-cli/src/dispatch.rs:277

}

fn resolve_init_distro(requested: Option<String>) -> Result<String> {
    resolve_init_distro_with(requested, std::env::var_os("ASTRID_ENFORCED_DISTRO"))
}

fn resolve_init_distro_with(
    requested: Option<String>,
    enforced: Option<OsString>,
) -> Result<String> {
    let Some(enforced) = enforced else {
        return non_empty_distro_source(requested).ok_or_else(|| {
            anyhow::anyhow!(
                "astrid init requires --distro <@owner/repo, URL, local Distro.toml, or .shuttle> unless ASTRID_ENFORCED_DISTRO is set by an embedding launcher; Astrid Runtime does not choose a product distro"
            )
        });
    };
    let enforced = enforced.into_string().map_err(|_| {
        anyhow::anyhow!("ASTRID_ENFORCED_DISTRO must contain a valid UTF-8 distro source")
    })?;
    if enforced.is_empty() {
        anyhow::bail!("ASTRID_ENFORCED_DISTRO must not be empty");
    }
    if requested.is_some() {
        anyhow::bail!(
            "astrid init cannot override the operator-enforced distro in ASTRID_ENFORCED_DISTRO"
        );
    }
    Ok(enforced)
}

fn non_empty_distro_source(source: Option<String>) -> Option<String> {
    source.filter(|source| !source.is_empty())
}

/// Route the root capsule-verb shorthand (`astrid <verb> [args…]`).
///

View on GitHub (pinned to affd8760f4)