unicity-aos/aos-ce · error

Capability ` ` must be a list.

Error message

Capability `{key}` must be a list.

What it means

`check_capabilities` validates each key in the `[capabilities]` table against known field kinds: list fields (in LIST_FIELDS) must be TOML arrays of scopes. If a key recognized as a list field holds a scalar or table instead of an array, this error is pushed with the offending key name.

Solutions

  1. Rewrite the value as an array: `{key} = ["scope"]`.
  2. If the capability is unused, remove the key entirely.
  3. Check which keys are in LIST_FIELDS in checks.rs to know the exact list-typed names.

Example fix

// before
[capabilities]
uplink = "net:read"

// after
[capabilities]
uplink = ["net:read"]
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

fn is_scope_list(v: &toml::Value) -> bool { v.is_array() }

Prevention

When it happens

Trigger: Setting a list-type capability field such as a scope list to a string or boolean, e.g. `uplink = true` or `allowed_scopes = "net:read"`.

Common situations: Confusing a single-value shorthand with the array form, editing an entry from `"scope"` to `["scope"]` incorrectly, or merging configs where the array brackets were lost.

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

Appendix: source

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

        ));
        return;
    };
    const LIST_FIELDS: &[&str] = &[
        "net",
        "kv",
        "fs_read",
        "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`.",
            ));
        }
    }

View on GitHub (pinned to f6f22024fb)