astrid-runtime/astrid · error

capsule ' ': tag must not contain surrounding whitespace

Error message

capsule '{}': tag must not contain surrounding whitespace

What it means

Like versions, capsule tags must be free of surrounding whitespace: validate_manifest trims the optional `tag` string and bails when the raw value differs from its trimmed form. Tags are used verbatim to resolve released capsule artifacts, so padded tags would fail lookup.

Solutions

  1. Strip surrounding whitespace from the `tag` value in the manifest.
  2. Trim the tag at generation time if the manifest is scripted.
  3. Re-run validation; note an all-whitespace tag will then hit the separate 'tag must not be empty' error — remove it instead if unintended.

Example fix

# before
[[capsules]]
name = "http"
tag = " v1.2.0 "

# after
[[capsules]]
name = "http"
tag = "v1.2.0"
Defensive patterns

Strategy: validation

Validate before calling

for cap in &manifest.capsules {
    if let Some(t) = &cap.tag {
        if t != t.trim() {
            panic!("capsule '{}': trim tag whitespace", cap.name);
        }
    }
}

Try / catch

if let Err(e) = validate_manifest(&manifest) {
    if e.to_string().contains("tag must not contain surrounding whitespace") {
        eprintln!("strip padding from tag: {e}");
    }
}

Prevention

When it happens

Trigger: A `[[capsules]]` entry with `tag = " v1.2.0 "` or a tag containing a trailing newline/tab.

Common situations: Copy-pasting git tags from terminals or docs with trailing spaces; generated manifests that interpolate untrimmed variables; editors inserting trailing whitespace on save.

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/929cb5dc2e4f043b. Report an issue: GitHub.

Appendix: source

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

        let version = cap.version.trim();
        if cap.version != version {
            anyhow::bail!(
                "capsule '{}': version must not contain surrounding whitespace",
                cap.name
            );
        }
        if !version.is_empty() && Version::parse(version).is_err() {
            anyhow::bail!(
                "capsule '{}': version '{}' is not valid semver",
                cap.name,
                cap.version
            );
        }
        let tag = cap.tag.as_deref().map(str::trim);
        if let Some(raw_tag) = cap.tag.as_deref()
            && raw_tag != raw_tag.trim()
        {
            anyhow::bail!(
                "capsule '{}': tag must not contain surrounding whitespace",
                cap.name
            );
        }
        if matches!(tag, Some("")) {
            anyhow::bail!("capsule '{}': tag must not be empty", cap.name);
        }
        if version.is_empty() && tag.is_none() {
            anyhow::bail!(
                "capsule '{}': distro capsules require a concrete released version or tag",
                cap.name
            );
        }
    }

    // At least one uplink.
    let has_uplink = manifest
        .capsules

View on GitHub (pinned to affd8760f4)