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
- Read v3_err — if it says 'No auth config found for toolkit', create the auth config in the Composio dashboard first
- Use the exact toolkit slug (e.g. 'github', 'gmail'), not a display name or capitalized variant
- Always pass 'app' when calling connect, since the v2 fallback cannot run from auth_config_id alone
- 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
- Always pass a canonical lowercase toolkit slug as 'app' — never a display name
- Ensure the workspace has an auth config for the toolkit before offering connect in the UI
- Pass 'app' even when using auth_config_id-adjacent flows so the v2 fallback remains usable
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
- Composio v3 connect failed: {err}
- Composio v2 connect failed: {err}
- Composio v3 auth config lookup failed: {err}
- No auth config found for toolkit '{app_name}'. Create one in
- composio.authorize: {AUTHORIZE_OAUTH_SCOPES_FIELD} entries m
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/803e6fc3a33c433c.
Report an issue: GitHub.