{"record":{"id":"82a0689dbc3f2f4d","repo":"tinyhumansai/openhuman","slug":"composio-client-unavailable-is-the-user-signed-i","errorCode":null,"errorMessage":"composio client unavailable — is the user signed in? ({e})","messagePattern":"composio client unavailable — is the user signed in\\? \\((.+?)\\)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/openhuman/agent/debug/mod.rs","lineNumber":288,"sourceCode":"                .map(|ci| ci.toolkit.clone())\n                .collect();\n            anyhow!(\n                \"toolkit `{toolkit}` is not connected. Connected toolkits: [{}]\",\n                connected.join(\", \")\n            )\n        })?;\n\n    // Resolve the live client kind via the mode-aware factory so a\n    // direct-mode user can still render the prompt even without a\n    // backend session (#1710 Wave 2). Backend mode keeps the existing\n    // `fetch_toolkit_actions` round-trip; direct mode skips the\n    // refresh (no backend allowlist to consult) and keeps the cached\n    // catalogue, mirroring `ComposioListToolsTool`'s short-circuit.\n    use crate::openhuman::integrations::composio::client::{\n        create_composio_client, ComposioClientKind,\n    };\n    let client_kind = create_composio_client(config)\n        .map_err(|e| anyhow!(\"composio client unavailable — is the user signed in? ({e})\"))?;\n\n    // Refresh the action catalogue for this toolkit at prompt-generation\n    // time so the dump reflects the **current** backend state rather\n    // than the session-start bulk fetch's snapshot (which can return an\n    // empty list for some toolkits even when the per-toolkit endpoint\n    // returns actions). Mirrors subagent_runner's typed-mode fallback:\n    // an empty fresh list or a network error keeps the cached catalogue\n    // rather than blanking it.\n    match &client_kind {\n        ComposioClientKind::Backend(composio_client) => {\n            match crate::openhuman::integrations::composio::fetch_toolkit_actions(\n                composio_client,\n                &integration.toolkit,\n                None,\n            )\n            .await\n            {\n                Ok(actions) if !actions.is_empty() => {","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/openhuman/agent/debug/mod.rs#L270-L306","documentation":"render_integrations_agent resolves the live Composio client via the mode-aware `create_composio_client(config)` (src/openhuman/agent/debug/mod.rs:288) and wraps failure with a sign-in hint. Failure means neither the backend Composio session nor a locally-usable direct-mode credential could be constructed from current config — typically no session token / not signed in, or a malformed local Composio key.","triggerScenarios":"Prompt-dumping the integrations_agent while signed out of the backend in backend mode with no local Composio credential; config carries a partially-specified composio section (key present but invalid shape); credentials store unreadable.","commonSituations":"Headless/CI environments that never completed sign-in; token expired and the app hasn't refreshed; switching between backend and direct mode leaving config half-populated.","solutions":["Sign in (the message's first suggestion) so the backend Composio client can be built.","Or complete direct-mode Composio configuration (local API key) in Connections.","Read the parenthesized inner `{e}` to distinguish missing-credential from malformed-config.","Retry after authenticating; `composio list_connection` succeeding is a good pre-check that the client is constructible."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Cheap pre-check that the Composio client is constructible:\nif crate::openhuman::integrations::composio::client::create_composio_client(&config).is_err() {\n    anyhow::bail!(\"sign in (or configure local Composio credentials) before dumping integrations prompts\");\n}","typeGuard":"fn composio_client_ready(config: &Config) -> bool {\n    crate::openhuman::integrations::composio::client::create_composio_client(config).is_ok()\n}","tryCatchPattern":"match create_composio_client(config) {\n    Ok(kind) => kind,\n    Err(e) => {\n        // Do not retry: credential absence is persistent. Surface the sign-in\n        // hint and the inner {e}; direct users to Connections to authenticate.\n        return Err(anyhow!(\"composio client unavailable — is the user signed in? ({e})\"));\n    }\n}","preventionTips":["Authenticate before any integrations prompt/tool usage; `composio list_connection` succeeding is a good canary.","For headless environments, configure direct-mode Composio credentials.","Re-check sign-in after token-expiry events instead of assuming the session persists."],"tags":["rust","integrations","composio","authentication","agent-prompts","debug"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}