zeroclaw-labs/zeroclaw · error

Composio v3 action execution failed: {err}

Error message

Composio v3 action execution failed: {err}

What it means

The per-attempt HTTP failure underneath the aggregated execute errors: POST {COMPOSIO_API_BASE_V3}/tools/execute/{slug} with body {version: latest, arguments|text, user_id?, connected_account_id?} returned a non-2xx status. response_error() formats the status plus Composio's error message with account/entity IDs redacted and a 240-char cap. Each such failure is collected by execute_action into the 'slug: <this message>' entries of the 1132/1133 aggregation, so end users normally see it embedded there.

Source

Thrown at crates/zeroclaw-tools/src/composio.rs:398

            params,
            text,
            entity_id,
            connected_account_ref,
        );

        ensure_https(&url)?;

        let resp = self
            .client()
            .post(&url)
            .header("x-api-key", &self.api_key)
            .json(&body)
            .send()
            .await?;

        if !resp.status().is_success() {
            let err = response_error(resp).await;
            anyhow::bail!("Composio v3 action execution failed: {err}");
        }

        let result: serde_json::Value = resp
            .json()
            .await
            .context("Failed to decode Composio v3 execute response")?;
        Ok(result)
    }

    /// Get the OAuth connection URL for a specific app/toolkit or auth config.
    /// Uses the v3 endpoint.
    pub async fn get_connection_url(
        &self,
        app_name: Option<&str>,
        auth_config_id: Option<&str>,
        entity_id: &str,
    ) -> anyhow::Result<ComposioConnectionLink> {
        self.get_connection_url_v3(app_name, auth_config_id, entity_id)

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Decode the embedded 'HTTP <code>': 404 -> get the exact slug via action='list'; 400 -> fix params per the schema hint; 401 -> fix composio.api_key; 429 -> back off.
  2. Pin the exact tool_slug so only one candidate is attempted.
  3. Verify the account with action='list_accounts' and pass connected_account_id.
  4. Re-run action='connect' if the account's OAuth token expired.

Example fix

// before: legacy alias + guessed params
let args = json!({"action": "execute", "action_name": "GITHUB_LIST_REPOS", "params": {}});

// after: exact v3 slug (lowercase, hyphenated) from action='list' + required params
let args = json!({"action": "execute", "tool_slug": "github-list-repositories", "params": {"owner": "zeroclaw"}});
Defensive patterns

Strategy: try-catch

Validate before calling

// Resolve the slug from the catalog and validate params before executing
let actions = tool.list_actions(app).await?;
if !actions.iter().any(|a| a.name == requested_slug) {
    anyhow::bail!("slug '{requested_slug}' not in app catalog; pick from action='list'");
}

Type guard

fn extract_composio_status(err: &str) -> Option<u16> {
    let idx = err.find("HTTP ")?;
    err[idx + 5..]
        .split(|c: char| !c.is_ascii_digit())
        .next()
        .and_then(|digits| digits.parse().ok())
}

Try / catch

// Do NOT blind-retry executes: they can have side effects (send an email twice).
match tool.execute(args).await {
    Ok(r) if r.success => {}
    Ok(r) => match extract_composio_status(&r.error.clone().unwrap_or_default()) {
        Some(429) | Some(500..=599) => { /* safe to retry once after backoff */ }
        _ => { /* inspect per-slug errors; fix params/slug/account */ }
    },
    Err(e) => { /* transport failure */ }
}

Prevention

When it happens

Trigger: 404: the slug candidate is not a real v3 tool; 400: arguments fail the tool's input schema (missing or invalid fields); 401: bad x-api-key; 403: workspace lacks the app; 429: rate limit; 5xx: backend error. Also 4xx when the connected account is missing or its OAuth token expired for the entity.

Common situations: Legacy uppercase action names (e.g. GITHUB_LIST_REPOS) tried against v3 slugs; params built from an outdated schema; API key from a different workspace; OAuth token expired since the last successful run.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/1a7f70c5e658fa84. Report an issue: GitHub.