unicity-aos/aos-ce · error

Capability ` ` must be a boolean.

Error message

Capability `{key}` must be a boolean.

What it means

Keys in BOOL_FIELDS (`uplink`, `allow_persistent`, `allow_prompt_injection`) must be TOML booleans. If one of them holds a string, integer, or other type, `check_capabilities` pushes this error. This keeps capability flags strictly typed so the runtime can rely on boolean semantics.

Solutions

  1. Change the value to a bare boolean: `{key} = true` or `false`.
  2. Omit the key entirely if the default (false) is acceptable.
  3. Remove surrounding quotes so TOML parses it as a boolean, not a string.

Example fix

// before
allow_persistent = "true"

// after
allow_persistent = true
Defensive patterns

Strategy: validation

Validate before calling

// Rust
if !value.is_bool() {
    return Err(format!("capability `{key}` must be a boolean"));
}

Type guard

fn is_bool_flag(v: &toml::Value) -> bool { v.is_bool() }

Prevention

When it happens

Trigger: Writing `uplink = "yes"`, `allow_persistent = 1`, or `allow_prompt_injection = "true"` in the [capabilities] table.

Common situations: Copying flags from YAML/JSON where strings are common, using 1/0 instead of true/false, or quoting the value accidentally.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13). Data as JSON: /api/errors/9c011add483b7bd0. Report an issue: GitHub.

Appendix: source

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

        "fs_write",
        "host_process",
        "net_bind",
        "net_connect",
        "identity",
    ];
    const BOOL_FIELDS: &[&str] = &["uplink", "allow_persistent", "allow_prompt_injection"];

    for (key, value) in capabilities {
        if LIST_FIELDS.contains(&key.as_str()) {
            if !value.is_array() {
                out.push(Finding::err(
                    format!("Capability `{key}` must be a list."),
                    format!("Use `{key} = [\"scope\"]`, or omit it when unused."),
                ));
            }
        } else if BOOL_FIELDS.contains(&key.as_str()) {
            if !value.is_bool() {
                out.push(Finding::err(
                    format!("Capability `{key}` must be a boolean."),
                    format!("Use `{key} = true` or omit it (the default is false)."),
                ));
            }
        } else {
            out.push(Finding::warn(
                format!("Unknown capability field `{key}`."),
                "Use only the current fields documented by `forge_guide` topic `capabilities`.",
            ));
        }
    }

    if capabilities
        .get("kv")
        .and_then(Toml::as_array)
        .is_some_and(|values| !values.is_empty())
    {
        out.push(Finding::info(

View on GitHub (pinned to f6f22024fb)