{"record":{"id":"be0740d532a83390","repo":"unicity-aos/aos-ce","slug":"ingress-pending-read-error-for-source-id-source-id-failing","errorCode":null,"errorMessage":"ingress pending read error for source_id '{source_id}', failing closed: {e}","messagePattern":"ingress pending read error for source_id '(.+?)', failing closed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/aos-mcp-broker/src/execute.rs","lineNumber":420,"sourceCode":"/// is one re-usable stale marker, never a denied legitimate grant).\npub(crate) fn take_ingress_pending(source_id: &str) -> bool {\n    let Some(key) = ingress_pending_key(source_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 ingress pending marker for source_id \\\n                     '{source_id}': {e}\",\n                    crate::profile::log_tag()\n                ));\n            }\n            true\n        }\n        Ok(None) => false,\n        Err(e) => {\n            log::warn(format!(\n                \"{}: ingress pending read error for source_id '{source_id}', \\\n                 failing closed: {e}\",\n                crate::profile::log_tag()\n            ));\n            false\n        }\n    }\n}\n\n/// KV key marking an outstanding capsule-grant consent prompt for a\n/// `(principal, capsule_id)` pair. KV is per-principal-scoped by the kernel,\n/// so the capsule id alone disambiguates within the keyspace — the principal\n/// is implicit in the storage scope, not the key suffix. Same empty-suffix\n/// guard as [`ingress_pending_key`]: an empty `capsule_id` must never resolve\n/// to a routable key (it would collapse to the bare prefix and let one marker\n/// dedup every grant prompt for the principal). The `principal` is accepted\n/// for symmetry with the call sites and to keep the dedup key intent explicit,\n/// but is NOT stamped into the suffix (the KV scope already carries it).","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/crates/aos-mcp-broker/src/execute.rs#L402-L438","documentation":"The MCP broker's take_ingress_pending looks up pending ingress state for a source_id in KV. If the read errors (as opposed to returning Ok(None)), the broker fails closed — treating the pending state as absent/denying continuation — and logs this warning prefixed with the broker's log tag.","triggerScenarios":"KV read of the ingress-pending entry for source_id returns Err inside take_ingress_pending — storage backend unavailable, decode failure of the stored value, or an I/O error on the pending record.","commonSituations":"KV store restart or network partition during an MCP execute flow; corrupted/unexpected bytes at the pending key after a schema change; source_id reused across broker restarts with stale records.","solutions":["Check the {e} detail and restore KV availability; retry the execute flow once the store is healthy.","Delete the corrupted pending record for that source_id so the next read is a clean miss.","Verify the stored pending value matches the current broker schema (version upgrade drift).","Expect fail-closed behavior: callers will see the flow as not-pending; re-initiate the ingress flow."],"exampleFix":"// before\nErr(e) => {\n    log::warn(format!(\"{}: ingress pending read error for source_id '{source_id}', \\\n         failing closed: {e}\", crate::profile::log_tag()));\n    false\n}\n// after\n// fix KV backend, or clear the bad key:\nkv::delete(&pending_key(source_id)).ok();\nErr(e) => {\n    log::warn(format!(\"{}: ingress pending read error for source_id '{source_id}', \\\n         failing closed: {e}\", crate::profile::log_tag()));\n    false\n}","handlingStrategy":"try-catch","validationCode":"// before relying on pending state, probe the store\nconst reachable = await kv.ping();\nif (!reachable) throw new Error('kv unavailable, execute flow will fail closed');","typeGuard":null,"tryCatchPattern":"match kv::get(&pending_key) {\n    Ok(Some(v)) => resume(v),\n    Ok(None) => /* not pending */ false,\n    Err(e) => { log::warn(\"ingress pending read error: {e}\"); false } // fail closed\n}","preventionTips":["Monitor KV availability during MCP execute flows","Version pending records to survive broker upgrades","Clear corrupt pending keys instead of retrying reads"],"tags":["kv","fail-closed","broker","state"],"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"}