{"record":{"id":"04f2dbaf88a62e9b","repo":"unicity-aos/aos-ce","slug":"grant-decision-read-error-for-capsule-id-capsule-id-will","errorCode":null,"errorMessage":"grant decision read error for capsule_id '{capsule_id}', will prompt: {e}","messagePattern":"grant decision read error for capsule_id '(.+?)', will prompt: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/aos-mcp-broker/src/grant_decision.rs","lineNumber":187,"sourceCode":"            crate::profile::log_tag()\n        ));\n    }\n}\n\n/// Read the durable recorded grant decision for `capsule_id`, or `None` if the\n/// user has not decided (or the record cannot be read / parsed).\n///\n/// Fail toward prompting: a missing key, a KV read error, or an unparseable\n/// value all return `None` so the broker surfaces a fresh consent prompt. It\n/// NEVER returns `Approve` on a read it is unsure about — an auto-approve must\n/// only ever follow a record the user actually created.\npub(crate) fn recorded_grant_decision(capsule_id: &str) -> Option<GrantDecision> {\n    let key = grant_decision_key(capsule_id)?;\n    match kv::get_bytes_opt(&key) {\n        Ok(Some(bytes)) => parse_grant_decision(&bytes),\n        Ok(None) => None,\n        Err(e) => {\n            log::warn(format!(\n                \"{}: grant decision read error for capsule_id '{capsule_id}', \\\n                 will prompt: {e}\",\n                crate::profile::log_tag()\n            ));\n            None\n        }\n    }\n}\n\n/// Map a recorded-decision read to the broker's [`GrantAction`].\n///\n/// Pure — the KV read happens in [`recorded_grant_decision`]; this is the\n/// testable decision spine (a recorded approve auto-responds, a recorded deny\n/// suppresses, no record prompts).\npub(crate) fn grant_action(decision: Option<GrantDecision>) -> GrantAction {\n    match decision {\n        Some(GrantDecision::Approve) => GrantAction::AutoApprove,\n        Some(GrantDecision::Deny) => GrantAction::AutoDeny,","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/crates/aos-mcp-broker/src/grant_decision.rs#L169-L205","documentation":"This warning is logged in `recorded_grant_decision` when reading a previously recorded grant decision for a capsule from the kv store fails with Err. The function degrades gracefully to None, meaning the broker will treat the decision as unknown and prompt the user again instead of reusing a possibly stale or wrong decision. It is not a hard failure — access is not granted without an explicit decision.","triggerScenarios":"Calling recorded_grant_decision(capsule_id) when kv::get_bytes_opt returns Err for the grant-decision key — storage backend error, corrupted bytes that cannot even be read, or backend unavailable.","commonSituations":"Embedded kv store IO failure or being reopened mid-request; corrupted decision bytes from an interrupted write; environment (container, tmpfs) where the store file is unreadable; version migration changing key layout.","solutions":["Check the underlying error `e` in the log and repair the kv backend (disk full, permissions, corrupted file).","Delete the unreadable grant-decision key so a fresh decision can be recorded on the next prompt.","Verify the store is not being written concurrently by another process with an incompatible format/version.","Accept the safe default: the user will be re-prompted; only investigate further if prompts repeat unexpectedly."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Pre-check the decision record before trusting it:\nfn decision_readable(capsule_id: &str) -> bool {\n    kv::get_bytes_opt(&grant_decision_key(capsule_id)).is_ok()\n}","typeGuard":null,"tryCatchPattern":"match kv::get_bytes_opt(&key) {\n    Ok(Some(bytes)) => parse_grant_decision(&bytes).unwrap_or(None),\n    Ok(None) => None,\n    Err(e) => { log::warn!(\"will prompt: {e}\"); None /* re-prompt user */ }\n}","preventionTips":["Write decision records atomically so interrupted writes never leave unreadable bytes.","Alert on repeated decision-read warnings; they mean users are being re-prompted unnecessarily.","Pin the kv store format/version and migrate keys explicitly on upgrades."],"tags":["kv-store","grant","fallback","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"}