{"record":{"id":"f8cd8a7a3e7e2921","repo":"tinyhumansai/openhuman","slug":"composio-v3-connect-failed-err","errorCode":null,"errorMessage":"Composio v3 connect failed: {err}","messagePattern":"Composio v3 connect failed: (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/openhuman/integrations/composio/tools/direct.rs","lineNumber":570,"sourceCode":"        };\n\n        let url = format!(\"{}/connected_accounts/link\", self.base_v3);\n        let body = json!({\n            \"auth_config_id\": auth_config_id,\n            \"user_id\": entity_id,\n        });\n\n        let resp = self\n            .client()\n            .post(&url)\n            .header(\"x-api-key\", &self.api_key)\n            .json(&body)\n            .send()\n            .await?;\n\n        if !resp.status().is_success() {\n            let err = response_error(resp).await;\n            anyhow::bail!(\"Composio v3 connect failed: {err}\");\n        }\n\n        let result: serde_json::Value = resp\n            .json()\n            .await\n            .context(\"Failed to decode Composio v3 connect response\")?;\n        extract_redirect_url(&result)\n            .ok_or_else(|| anyhow::anyhow!(\"No redirect URL in Composio v3 response\"))\n    }\n\n    async fn get_connection_url_v2(\n        &self,\n        app_name: &str,\n        entity_id: &str,\n    ) -> anyhow::Result<String> {\n        let url = format!(\"{}/connectedAccounts\", self.base_v2);\n\n        let body = json!({","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/integrations/composio/tools/direct.rs#L552-L588","documentation":"Non-2xx from the v3 POST that initiates an OAuth connection (get_connection_url_v3). The body carries provider/app identifiers and the entity; response_error folds status + body into {err}. On success the code extracts a redirect URL — this error is the non-2xx branch before that.","triggerScenarios":"auth_config_id that does not exist or belongs to another workspace; toolkit_slug with no auth config; 401 invalid API key; 429/5xx. Example: get_connection_url(Some(\"jira\"), None, entity) when the workspace has no Jira auth config.","commonSituations":"Stale auth_config_id cached from a previous workspace; toolkit slug typo; trying to connect an app the Composio account has not enabled.","solutions":["Inspect {err} for the status and Composio's message","If it points at a missing auth config, create one in the Composio dashboard for that toolkit, or pass a known-good auth_config_id","Confirm the toolkit slug spelling matches Composio's registry","401: re-enter the API key in Connections > Composio"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match tool.get_connection_url_v3_path(app, auth_config_id, &entity).await {\n    Ok(url) => Ok(url),\n    Err(e) => {\n        let msg = format!(\"{e:#}\");\n        if msg.contains(\"No auth config\") || msg.contains(\"404\") {\n            ui.explain_create_auth_config(app); // user must configure Composio first\n        }\n        Err(e)\n    }\n}","preventionTips":["Verify auth_config_id values are current for the workspace before persisting them","Normalize toolkit slugs (trim + lowercase) at input","Check the API key works before starting an OAuth handshake"],"tags":["composio","connect","http-error","v3","oauth"],"backgroundTag":"upstream-api-error-status","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}