{"record":{"id":"a719fd7d9e999891","repo":"tinyhumansai/openhuman","slug":"composio-direct-mode-selected-but-no-api-key-is-co","errorCode":null,"errorMessage":"composio direct mode selected but no api key is configured (set via composio.set_api_key RPC or config.composio.api_key)","messagePattern":"composio direct mode selected but no api key is configured \\(set via composio\\.set_api_key RPC or config\\.composio\\.api_key\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/integrations/composio/client.rs","lineNumber":833,"sourceCode":"            })?;\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!(\n                key_len = api_key.len(),\n                \"[composio-factory] resolved direct variant (key redacted)\"\n            );\n            Ok(ComposioClientKind::Direct(tool))\n        }\n        unknown => {\n            tracing::warn!(mode = %unknown, \"[composio-factory] unknown composio mode\");\n            Err(anyhow::anyhow!(\n                \"unknown composio mode: \\\"{unknown}\\\". Supported: \\\"backend\\\", \\\"direct\\\"\"\n            ))\n        }","sourceCodeStart":815,"sourceCodeEnd":851,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/integrations/composio/client.rs#L815-L851","documentation":"Direct mode was selected in config.composio.mode but neither the keychain nor config.toml holds a non-empty Composio API key, so no direct client can be constructed. The keychain is checked first; config.toml is the power-user fallback.","triggerScenarios":"Thrown at src/openhuman/integrations/composio/client.rs:833 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Set the key via the composio.set_api_key RPC (stores it in the encrypted keychain)","Or set config.composio.api_key in config.toml","Or switch mode back to \"backend\" and sign in instead"],"exampleFix":null,"handlingStrategy":"validation","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"}