{"record":{"id":"03ea4a9ad72d58ea","repo":"tinyhumansai/openhuman","slug":"failed-to-read-stored-composio-api-key-e","errorCode":null,"errorMessage":"failed to read stored composio api key: {e}","messagePattern":"failed to read stored composio api key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/integrations/composio/client.rs","lineNumber":822,"sourceCode":"    match mode {\n        // Empty string is treated as the default for forward compatibility\n        // with hand-edited configs that omit the field — `serde(default)`\n        // already gives us \"backend\" for missing fields, but a literal\n        // empty string in TOML would otherwise be rejected.\n        \"\" | MODE_BACKEND_PAT => {\n            let client = build_composio_client(config).ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"composio backend mode unavailable: no backend session token. \\\n                     Sign in first (auth_store_session).\"\n                )\n            })?;\n            tracing::debug!(\"[composio-factory] resolved backend variant\");\n            Ok(ComposioClientKind::Backend(client))\n        }\n        MODE_DIRECT_PAT => {\n            // Prefer keychain-stored key; fall back to `config.toml`.\n            let stored = crate::openhuman::security::credentials::get_composio_api_key(config)\n                .map_err(|e| anyhow::anyhow!(\"failed to read stored composio api key: {e}\"))?;\n            let api_key = stored\n                .or_else(|| {\n                    config\n                        .composio\n                        .api_key\n                        .as_ref()\n                        .map(|k| k.trim().to_string())\n                        .filter(|k| !k.is_empty())\n                })\n                .ok_or_else(|| {\n                    anyhow::anyhow!(\n                        \"composio direct mode selected but no api key is configured \\\n                         (set via composio.set_api_key RPC or config.composio.api_key)\"\n                    )\n                })?;\n\n            let tool = create_direct_composio_tool_for_api_key(config, &api_key)?;\n            tracing::debug!(","sourceCodeStart":804,"sourceCodeEnd":840,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/integrations/composio/client.rs#L804-L840","documentation":"In direct mode, reading the keychain-stored Composio API key (security::credentials::get_composio_api_key) failed. This is a credential-store read failure, not a missing key — the subsequent code falls back to config.toml only when the read returns Ok(None).","triggerScenarios":"Thrown at src/openhuman/integrations/composio/client.rs:822 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the keyring/keychain backend is available and unlocked","Re-store the Composio API key via composio.set_api_key","As a workaround set config.composio.api_key in config.toml once the read failure is resolved"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}