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
- Rewrite the value as an array: `{key} = ["scope"]`.
- If the capability is unused, remove the key entirely.
- 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
- Always write scope capabilities as arrays, even for a single scope.
- Consult LIST_FIELDS in checks.rs for the definitive list of array-typed keys.
- Keep a lint step in pre-commit hooks.
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
- Capability ` ` must be a boolean.
- `capabilities` must be a TOML table.
- [package].name is missing or empty.
- [package].version is missing.
- No [[component]] with a `file` was found.
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)