astrid-runtime/astrid · error

distro.id '{}' is invalid (must match ^[a-z][a-z0-9-]*$)

Error message

distro.id '{}' is invalid (must match ^[a-z][a-z0-9-]*$)

What it means

validate_manifest enforces that distro.id matches ^[a-z][a-z0-9-]*$ — a lowercase identifier usable in file paths, package names, and URLs. An ID violating this pattern is rejected because it could break path handling or downstream naming rules.

Source

Thrown at crates/astrid-cli/src/commands/distro/validate.rs:88

/// - Variable references in capsule env resolve to defined variables
/// - Requires version strings are valid semver requirements
#[allow(
    clippy::too_many_lines,
    reason = "flat sequence of independent validation checks; \
              inlining keeps the full ruleset auditable in one place"
)]
pub(crate) fn validate_manifest(manifest: &DistroManifest) -> anyhow::Result<()> {
    // Schema version.
    if manifest.schema_version != SCHEMA_VERSION {
        anyhow::bail!(
            "unsupported schema-version {} (expected {SCHEMA_VERSION})",
            manifest.schema_version,
        );
    }

    // Distro ID format.
    if !is_valid_id(&manifest.distro.id) {
        anyhow::bail!(
            "distro.id '{}' is invalid (must match ^[a-z][a-z0-9-]*$)",
            manifest.distro.id,
        );
    }

    // Distro version is valid semver.
    if semver::Version::parse(&manifest.distro.version).is_err() {
        anyhow::bail!(
            "distro.version '{}' is not valid semver",
            manifest.distro.version,
        );
    }

    // astrid-version is valid semver requirement (if set).
    if let Some(ref av) = manifest.distro.astrid_version
        && semver::VersionReq::parse(av).is_err()
    {
        anyhow::bail!("distro.astrid-version '{av}' is not a valid semver requirement");

View on GitHub (pinned to affd8760f4)

Solutions

  1. Rename the distro id to lowercase letters/digits/hyphens starting with a letter (e.g. my-distro)
  2. Replace underscores with hyphens and drop invalid characters
  3. Move a human-readable title to a separate metadata field if one exists

Example fix

// before
// [distro]
// id = "My_Distro1"
// after
// [distro]
// id = "my-distro1"
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_id(id: &str) -> bool {
    !id.is_empty()
        && id.chars().next().map_or(false, |c| c.is_ascii_lowercase())
        && id.chars().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-')
}

Prevention

When it happens

Trigger: Distro.toml whose [distro] id contains uppercase letters, underscores, spaces, digits at the start, or is empty.

Common situations: Naming the distro after a product with capitals ("MyDistro"); using snake_case out of habit; leading digits copied from a version number.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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