{"record":{"id":"9c011add483b7bd0","repo":"unicity-aos/aos-ce","slug":"capability-key-must-be-a-boolean","errorCode":null,"errorMessage":"Capability `{key}` must be a boolean.","messagePattern":"Capability `(.+?)` must be a boolean\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"capsules/capsule-forge/src/checks.rs","lineNumber":114,"sourceCode":"        \"fs_write\",\n        \"host_process\",\n        \"net_bind\",\n        \"net_connect\",\n        \"identity\",\n    ];\n    const BOOL_FIELDS: &[&str] = &[\"uplink\", \"allow_persistent\", \"allow_prompt_injection\"];\n\n    for (key, value) in capabilities {\n        if LIST_FIELDS.contains(&key.as_str()) {\n            if !value.is_array() {\n                out.push(Finding::err(\n                    format!(\"Capability `{key}` must be a list.\"),\n                    format!(\"Use `{key} = [\\\"scope\\\"]`, or omit it when unused.\"),\n                ));\n            }\n        } else if BOOL_FIELDS.contains(&key.as_str()) {\n            if !value.is_bool() {\n                out.push(Finding::err(\n                    format!(\"Capability `{key}` must be a boolean.\"),\n                    format!(\"Use `{key} = true` or omit it (the default is false).\"),\n                ));\n            }\n        } else {\n            out.push(Finding::warn(\n                format!(\"Unknown capability field `{key}`.\"),\n                \"Use only the current fields documented by `forge_guide` topic `capabilities`.\",\n            ));\n        }\n    }\n\n    if capabilities\n        .get(\"kv\")\n        .and_then(Toml::as_array)\n        .is_some_and(|values| !values.is_empty())\n    {\n        out.push(Finding::info(","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/capsules/capsule-forge/src/checks.rs#L96-L132","documentation":"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.","triggerScenarios":"Writing `uplink = \"yes\"`, `allow_persistent = 1`, or `allow_prompt_injection = \"true\"` in the [capabilities] table.","commonSituations":"Copying flags from YAML/JSON where strings are common, using 1/0 instead of true/false, or quoting the value accidentally.","solutions":["Change the value to a bare boolean: `{key} = true` or `false`.","Omit the key entirely if the default (false) is acceptable.","Remove surrounding quotes so TOML parses it as a boolean, not a string."],"exampleFix":"// before\nallow_persistent = \"true\"\n\n// after\nallow_persistent = true","handlingStrategy":"validation","validationCode":"// Rust\nif !value.is_bool() {\n    return Err(format!(\"capability `{key}` must be a boolean\"));\n}","typeGuard":"fn is_bool_flag(v: &toml::Value) -> bool { v.is_bool() }","tryCatchPattern":null,"preventionTips":["Never quote boolean values in TOML.","Avoid 1/0; use true/false literals only.","Verify flags against BOOL_FIELDS: uplink, allow_persistent, allow_prompt_injection."],"tags":["toml","type-mismatch","schema-validation","config"],"backgroundTag":"type-mismatch","analyzedSha":"f6f22024fb1e8d122f28a1b4a9f75aee448ae839","analyzedAt":"2026-09-13T03:04:44.565Z","contentChangedAt":"2026-09-13T03:04:44.565Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}