{"record":{"id":"51800cdbd93a5358","repo":"unicity-aos/aos-ce","slug":"grant-pending-read-error-for-capsule-id-capsule-id-failing","errorCode":null,"errorMessage":"grant pending read error for capsule_id '{capsule_id}', failing closed: {e}","messagePattern":"grant pending read error for capsule_id '(.+?)', failing closed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/aos-mcp-broker/src/execute.rs","lineNumber":588,"sourceCode":"/// confirmed-present marker is logged but reported as consumed.\npub(crate) fn take_grant_pending(principal: &str, capsule_id: &str) -> bool {\n    let Some(key) = grant_pending_key(principal, capsule_id) else {\n        return false;\n    };\n    match kv::get_bytes_opt(&key) {\n        Ok(Some(_)) => {\n            if let Err(e) = kv::delete(&key) {\n                log::warn(format!(\n                    \"{}: failed to clear grant pending marker for capsule_id \\\n                     '{capsule_id}': {e}\",\n                    crate::profile::log_tag()\n                ));\n            }\n            true\n        }\n        Ok(None) => false,\n        Err(e) => {\n            log::warn(format!(\n                \"{}: grant pending read error for capsule_id '{capsule_id}', \\\n                 failing closed: {e}\",\n                crate::profile::log_tag()\n            ));\n            false\n        }\n    }\n}\n\n/// Confused-deputy guard for state-mutating broker calls.\n///\n/// `source_id` is the kernel-set UUID of the capsule that originated the\n/// inbound IPC message ([`astrid_sdk::runtime::caller`] →\n/// `CallerContext::source_id`). It is NOT guest-settable — the kernel\n/// stamps it from the publishing capsule's invocation context, so a\n/// malicious guest cannot forge it the way it could forge a body field.\n/// An ingress is trusted iff the per-(principal, source_id) KV key\n/// `mcp.ingress.trust.<source_id>` exists — written ONLY by","sourceCodeStart":570,"sourceCodeEnd":606,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/crates/aos-mcp-broker/src/execute.rs#L570-L606","documentation":"This is a warning log emitted in `take_grant_pending` when reading a pending grant record from the key-value store for a capsule fails (kv::take/get returns Err). The broker deliberately 'fails closed': it treats the unknown state as if no pending grant exists (returns false), so the operation is denied or the caller is re-prompted rather than silently approved. The log is diagnostic — the error value `e` carries the underlying storage failure.","triggerScenarios":"Calling take_grant_pending(capsule_id) when the underlying kv backend returns Err on the read/take of the pending-grant key — e.g. storage corruption, backend I/O failure, lock contention, or a malformed record the store cannot deserialize.","commonSituations":"KV store backend temporarily unavailable or restarting; corrupted grant record left by a crashed broker; permission or IO errors on the embedded store; concurrent take by another broker instance that leaves the record in a bad state.","solutions":["Inspect the underlying error `e` in the log to identify the kv backend failure (IO, lock, deserialization) and fix that root cause.","Check kv store health/integrity (e.g. reopen or repair the store) and verify the capsule's pending-grant key can be read.","Confirm no concurrent broker process is contending for the same grant record; ensure single-writer or proper locking.","If the record is corrupt, delete the stale pending-grant key so the capsule can re-request a fresh grant (fail-closed means the user will be prompted again)."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Before relying on take_grant_pending, probe readability:\nfn grant_pending_readable(capsule_id: &str) -> bool {\n    match kv::get_bytes_opt(&grant_pending_key(capsule_id)) {\n        Ok(_) => true,\n        Err(e) => { log::warn!(\"grant store unreadable: {e}\"); false }\n    }\n}","typeGuard":null,"tryCatchPattern":"match kv::take_bytes(&key) {\n    Ok(Some(b)) => parse(b),\n    Ok(None) => /* no pending grant */,\n    Err(e) => { log::warn!(\"failing closed: {e}\"); /* treat as no grant, deny */ }\n}","preventionTips":["Run health checks on the kv backend before processing grant traffic.","Monitor warn logs for repeated 'grant pending read error' — recurring failures indicate backend corruption.","Use atomic, single-writer access to grant records to avoid torn reads."],"tags":["kv-store","grant","fail-closed","storage"],"backgroundTag":"database-query-failed","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"}