tinyhumansai/openhuman · error · anyhow::Error

composio client unavailable — is the user signed in? ({e})

Error message

composio client unavailable — is the user signed in? ({e})

What it means

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.

Source

Thrown at src/openhuman/agent/debug/mod.rs:288

                .map(|ci| ci.toolkit.clone())
                .collect();
            anyhow!(
                "toolkit `{toolkit}` is not connected. Connected toolkits: [{}]",
                connected.join(", ")
            )
        })?;

    // Resolve the live client kind via the mode-aware factory so a
    // direct-mode user can still render the prompt even without a
    // backend session (#1710 Wave 2). Backend mode keeps the existing
    // `fetch_toolkit_actions` round-trip; direct mode skips the
    // refresh (no backend allowlist to consult) and keeps the cached
    // catalogue, mirroring `ComposioListToolsTool`'s short-circuit.
    use crate::openhuman::integrations::composio::client::{
        create_composio_client, ComposioClientKind,
    };
    let client_kind = create_composio_client(config)
        .map_err(|e| anyhow!("composio client unavailable — is the user signed in? ({e})"))?;

    // Refresh the action catalogue for this toolkit at prompt-generation
    // time so the dump reflects the **current** backend state rather
    // than the session-start bulk fetch's snapshot (which can return an
    // empty list for some toolkits even when the per-toolkit endpoint
    // returns actions). Mirrors subagent_runner's typed-mode fallback:
    // an empty fresh list or a network error keeps the cached catalogue
    // rather than blanking it.
    match &client_kind {
        ComposioClientKind::Backend(composio_client) => {
            match crate::openhuman::integrations::composio::fetch_toolkit_actions(
                composio_client,
                &integration.toolkit,
                None,
            )
            .await
            {
                Ok(actions) if !actions.is_empty() => {

View on GitHub (pinned to a221052e0d)

Solutions

  1. Sign in (the message's first suggestion) so the backend Composio client can be built.
  2. Or complete direct-mode Composio configuration (local API key) in Connections.
  3. Read the parenthesized inner `{e}` to distinguish missing-credential from malformed-config.
  4. Retry after authenticating; `composio list_connection` succeeding is a good pre-check that the client is constructible.
Defensive patterns

Strategy: validation

Validate before calling

// Cheap pre-check that the Composio client is constructible:
if crate::openhuman::integrations::composio::client::create_composio_client(&config).is_err() {
    anyhow::bail!("sign in (or configure local Composio credentials) before dumping integrations prompts");
}

Type guard

fn composio_client_ready(config: &Config) -> bool {
    crate::openhuman::integrations::composio::client::create_composio_client(config).is_ok()
}

Try / catch

match create_composio_client(config) {
    Ok(kind) => kind,
    Err(e) => {
        // Do not retry: credential absence is persistent. Surface the sign-in
        // hint and the inner {e}; direct users to Connections to authenticate.
        return Err(anyhow!("composio client unavailable — is the user signed in? ({e})"));
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/82a0689dbc3f2f4d. Report an issue: GitHub.