unicity-aos/aos-ce · error

No [[component]] with a `file` was found.

Error message

No [[component]] with a `file` was found.

What it means

`check_component` scans all `[[component]]` entries and requires at least one to have a non-empty `file` string pointing at the capsule's WASM artifact. If none does (`has_file` is false), this error is emitted. Without a component file the manifest does not describe a runnable capsule.

Solutions

  1. Add a [[component]] table with `id`, `file = "my_capsule.wasm"`, and `type = "executable"`.
  2. If a [[component]] exists, add its `file` key pointing to the built WASM path.
  3. Ensure the file value is non-empty and matches the actual artifact name after `capsule-forge` build.

Example fix

// before
[[component]]
id = "main"

// after
[[component]]
id = "main"
file = "my_capsule.wasm"
type = "executable"
Defensive patterns

Strategy: validation

Validate before calling

// Rust
let has_file = root.get("component")
    .and_then(|c| c.as_array())
    .map_or(false, |cs| cs.iter().any(|c|
        c.get("file").and_then(|f| f.as_str()).map_or(false, |f| !f.is_empty())));
if !has_file { return Err("no [[component]] with a file"); }

Prevention

When it happens

Trigger: Capsule.toml with no [[component]] sections at all; [[component]] entries missing the `file` key; or `file = ""` (empty strings fail the `!f.is_empty()` test).

Common situations: Generating a manifest stub without the component table, renaming the WASM output and deleting the file key, or leaving a placeholder empty value before the build produced the artifact.

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/608b5470fb9c54d9. Report an issue: GitHub.

Appendix: source

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

        )),
        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.",
            "Add a [[component]] table with `id`, `file = \"my_capsule.wasm\"`, `type = \"executable\"`.",
        ));
    }
}

fn check_env(root: &Toml, out: &mut Vec<Finding>) {
    let Some(env) = root.get("env").and_then(Toml::as_table) else {
        return;
    };
    for (key, val) in env {
        if val.get("scope").and_then(Toml::as_str) == Some("shared") {
            out.push(Finding::warn(
                format!("[env].{key} sets scope = \"shared\", which is silently ignored."),
                "Remove `scope`; shared/operator-only env scope is not honoured from the manifest.",
            ));
        }
    }

View on GitHub (pinned to f6f22024fb)