tinyhumansai/openhuman · error · anyhow::Error

Composio connect failed on v3 ({v3_err}) and v2 fallback ({v

Error message

Composio connect failed on v3 ({v3_err}) and v2 fallback ({v2_err})

What it means

get_connection_url tries v3 connect (app_name or auth_config_id) and falls back to v2 (which requires an app name); this error means both failed. The v3 half usually carries the root cause — unknown toolkit, no auth config for it (see the companion 'No auth config found' error), or 401 — while the v2 half re-fails on the legacy appName route.

Source

Thrown at src/openhuman/integrations/composio/tools/direct.rs:530

        &self,
        app_name: Option<&str>,
        auth_config_id: Option<&str>,
        entity_id: &str,
    ) -> anyhow::Result<String> {
        let v3 = self
            .get_connection_url_v3(app_name, auth_config_id, entity_id)
            .await;
        match v3 {
            Ok(url) => Ok(url),
            Err(v3_err) => {
                let app = app_name.ok_or_else(|| {
                    anyhow::anyhow!(
                        "Composio v3 connect failed ({v3_err}) and v2 fallback requires 'app'"
                    )
                })?;
                match self.get_connection_url_v2(app, entity_id).await {
                    Ok(url) => Ok(url),
                    Err(v2_err) => anyhow::bail!(
                        "Composio connect failed on v3 ({v3_err}) and v2 fallback ({v2_err})"
                    ),
                }
            }
        }
    }

    async fn get_connection_url_v3(
        &self,
        app_name: Option<&str>,
        auth_config_id: Option<&str>,
        entity_id: &str,
    ) -> anyhow::Result<String> {
        let auth_config_id = match auth_config_id {
            Some(id) => id.to_string(),
            None => {
                let app = app_name.ok_or_else(|| {
                    anyhow::anyhow!("Missing 'app' or 'auth_config_id' for v3 connect")

View on GitHub (pinned to 7491200858)

Solutions

  1. Read v3_err — if it says 'No auth config found for toolkit', create the auth config in the Composio dashboard first
  2. Use the exact toolkit slug (e.g. 'github', 'gmail'), not a display name or capitalized variant
  3. Always pass 'app' when calling connect, since the v2 fallback cannot run from auth_config_id alone
  4. Verify the API key and that it belongs to the workspace holding the auth configs
Defensive patterns

Strategy: validation

Validate before calling

// The v2 fallback requires `app`; always supply it so a v3 blip can still connect.
let app = app.map(str::trim).filter(|a| !a.is_empty());
if app.is_none() && auth_config_id.is_none() {
    anyhow::bail!("connect requires 'app' or 'auth_config_id'");
}
tool.get_connection_url(app, auth_config_id, &entity).await?;

Try / catch

match tool.get_connection_url(app, auth_config_id, &entity).await {
    Ok(url) => ui.open(url),
    Err(e) => {
        let msg = format!("{e:#}");
        if msg.contains("No auth config found") {
            ui.explain_create_auth_config(app);
        } else if msg.contains("401") {
            ui.prompt_reenter_composio_key();
        }
    }
}

Prevention

When it happens

Trigger: Calling connect with an app slug that has no auth config in the Composio workspace; a misspelled/renamed toolkit slug; invalid API key; and the v2 fallback additionally requires 'app', so a v3 failure plus auth_config_id-only input fails v2 for that reason.

Common situations: User types a display name ('Google Mail') instead of the toolkit slug ('gmail'); toolkit not yet configured in the Composio workspace; key from a different workspace where the auth config does not exist.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/803e6fc3a33c433c. Report an issue: GitHub.