astrid-runtime/astrid · error

Capsule.toml has no package.name

Error message

Capsule.toml has no package.name

What it means

manifest_identity parses the Capsule.toml manifest from a source directory and extracts the package id from package.name. If the manifest lacks the [package] table or its name string key, the library throws because the capsule cannot be identified for publishing.

Source

Thrown at crates/astrid-capsule-install/src/storage.rs:725

                continue;
            }
            fs::copy(path, destination)?;
        } else {
            bail!("legacy capsule contains special file {}", path.display());
        }
    }
    Ok(())
}

fn manifest_identity(source_dir: &Path) -> anyhow::Result<(String, String)> {
    let manifest = fs::read_to_string(source_dir.join("Capsule.toml"))
        .with_context(|| format!("read capsule manifest from {}", source_dir.display()))?;
    let value: toml::Value = toml::from_str(&manifest).context("parse capsule manifest")?;
    let id = value
        .get("package")
        .and_then(|package| package.get("name"))
        .and_then(toml::Value::as_str)
        .ok_or_else(|| anyhow::anyhow!("Capsule.toml has no package.name"))?;
    let version = value
        .get("package")
        .and_then(|package| package.get("version"))
        .and_then(toml::Value::as_str)
        .ok_or_else(|| anyhow::anyhow!("Capsule.toml has no package.version"))?;
    Ok((id.to_owned(), version.to_owned()))
}

fn authority_capsule_id(authority: &[u8]) -> anyhow::Result<String> {
    let authority: InstalledAuthority =
        serde_json::from_slice(authority).context("decode authority receipt for package id")?;
    if authority.capsule_id.is_empty() {
        bail!("authority receipt has an empty capsule id");
    }
    Ok(authority.capsule_id)
}

/// Build a deterministic gzip/tar package from a checked directory.

View on GitHub (pinned to affd8760f4)

Solutions

  1. Add a [package] section with a string name field to Capsule.toml and republish.
  2. Validate Capsule.toml parses as expected (e.g. toml-lint) and confirm the key is exactly `name` under `[package]`.
  3. Regenerate the manifest with the current capsule tooling if it was produced by an older format.

Example fix

// before: Capsule.toml without package name
// after:
// [package]
// name = "my-capsule"
// version = "0.1.0"
Defensive patterns

Strategy: validation

Validate before calling

fn manifest_has_name(capsule_dir: &Path) -> anyhow::Result<()> {
    let raw = std::fs::read_to_string(capsule_dir.join("Capsule.toml"))?;
    let v: toml::Value = toml::from_str(&raw)?;
    if v.get("package").and_then(|p| p.get("name")).and_then(|n| n.as_str()).is_some() {
        Ok(())
    } else {
        Err(anyhow::anyhow!("Capsule.toml missing [package].name string"))
    }
}

Prevention

When it happens

Trigger: publish_directory_package reads Capsule.toml in source_dir, TOML parsing succeeds, but value.get("package").get("name").as_str() is None — no [package] section, no name key, or name is not a string.

Common situations: Hand-written or truncated Capsule.toml missing the package table; typos like [pacakge] or name = 123 (non-string); manifest generated by an older tooling version with a different schema.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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