unicity-aos/aos-ce · error

[package].version is missing.

Error message

[package].version is missing.

What it means

In the `check_package` version match, the `None` arm handles a missing `[package].version` key (or a non-string version, since `as_str()` yields None). The linter emits this distinct error from the malformed-version case so the developer knows exactly what to add. A version is mandatory for every capsule.

Solutions

  1. Add `version = "0.1.0"` under [package].
  2. If version exists as a number, quote it: `version = "1.0.0"`.
  3. Adopt a semver string you can keep bumping per release.

Example fix

// before
[package]
name = "my-capsule"

// after
[package]
name = "my-capsule"
version = "0.1.0"
Defensive patterns

Strategy: validation

Validate before calling

// Rust
if root.get("package").and_then(|p| p.get("version")).and_then(|v| v.as_str()).is_none() {
    return Err("[package].version is missing");
}

Prevention

When it happens

Trigger: Capsule.toml has [package] but no `version` key, or `version` is set to a non-string TOML type (integer/float) so `as_str()` returns None.

Common situations: Hand-writing a fresh manifest without versioning, deleting the version during a rename, or writing `version = 1` instead of a quoted string.

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 unicity-aos/aos-ce@f6f22024fb (2026-09-13). Data as JSON: /api/errors/5e3ddda032d9f53d. Report an issue: GitHub.

Appendix: source

Thrown at capsules/capsule-forge/src/checks.rs:154

    }
}

fn check_package(root: &Toml, out: &mut Vec<Finding>) {
    let pkg = root.get("package");
    let name = pkg.and_then(|p| p.get("name")).and_then(Toml::as_str);
    if name.is_none_or(str::is_empty) {
        out.push(Finding::err(
            "[package].name is missing or empty.",
            "Add `name = \"my-capsule\"` under [package].",
        ));
    }
    match pkg.and_then(|p| p.get("version")).and_then(Toml::as_str) {
        Some(v) if is_semverish(v) => {}
        Some(v) => out.push(Finding::err(
            format!("[package].version = \"{v}\" is not MAJOR.MINOR.PATCH."),
            "Use a three-part numeric version like \"0.1.0\".",
        )),
        None => out.push(Finding::err(
            "[package].version is missing.",
            "Add `version = \"0.1.0\"` under [package].",
        )),
    }
}

fn check_component(root: &Toml, out: &mut Vec<Finding>) {
    let comps = root.get("component").and_then(Toml::as_array);
    let has_file = comps.is_some_and(|arr| {
        arr.iter().any(|c| {
            c.get("file")
                .and_then(Toml::as_str)
                .is_some_and(|f| !f.is_empty())
        })
    });
    if !has_file {
        out.push(Finding::err(
            "No [[component]] with a `file` was found.",

View on GitHub (pinned to f6f22024fb)