{"record":{"id":"b6ea29bcfda2b8e6","repo":"zeroclaw-labs/zeroclaw","slug":"no-auth-config-found-for-toolkit-app-name-cre","errorCode":null,"errorMessage":"No auth config found for toolkit '{app_name}'. Create one in Composio first.","messagePattern":"No auth config found for toolkit '(.+?)'\\. Create one in Composio first\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/composio.rs","lineNumber":535,"sourceCode":"                (\"toolkit_slug\", app_name),\n                (\"show_disabled\", \"true\"),\n                (\"limit\", \"25\"),\n            ])\n            .send()\n            .await?;\n\n        if !resp.status().is_success() {\n            let err = response_error(resp).await;\n            anyhow::bail!(\"Composio v3 auth config lookup failed: {err}\");\n        }\n\n        let body: ComposioAuthConfigsResponse = resp\n            .json()\n            .await\n            .context(\"Failed to decode Composio v3 auth configs response\")?;\n\n        if body.items.is_empty() {\n            anyhow::bail!(\n                \"No auth config found for toolkit '{app_name}'. Create one in Composio first.\"\n            );\n        }\n\n        let preferred = body\n            .items\n            .iter()\n            .find(|cfg| cfg.is_enabled())\n            .or_else(|| body.items.first())\n            .context(\"No usable auth config returned by Composio\")?;\n\n        Ok(preferred.id.clone())\n    }\n}\n\n#[async_trait]\nimpl Tool for ComposioTool {\n    fn name(&self) -> &str {","sourceCodeStart":517,"sourceCodeEnd":553,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/composio.rs#L517-L553","documentation":"resolve_auth_config_id got HTTP 200 from GET /auth_configs but the items array is empty for toolkit_slug={app} — note show_disabled=true is already in the query, so disabled configs would still be listed. The Composio workspace behind the API key has no auth config (app credential) for that toolkit, so there is nothing to mint an OAuth link against. Raised from action='connect' when auth_config_id is omitted; the Tool wrapper surfaces it as 'Failed to get connection URL: No auth config found for toolkit ...' with success=false.","triggerScenarios":"action='connect' with app='github' before any GitHub auth config exists in the Composio workspace; an app slug that matches no toolkit so the filtered list comes back empty; the config lives in a different workspace than the API key.","commonSituations":"First-time integration setup where developers assume Composio ships default credentials per app; personal vs organization workspace key mix-ups; slug spelling mistakes that silently match nothing.","solutions":["Create the auth config for the toolkit in the Composio dashboard (same account/workspace as the API key), then retry action='connect'.","Confirm the app slug is the exact toolkit slug (check with action='list').","If you already know the config id, pass auth_config_id to skip resolution entirely.","Verify the API key's workspace actually holds the config."],"exampleFix":"// before: no auth config for 'linear' in this workspace yet\nlet args = json!({\"action\": \"connect\", \"app\": \"linear\"});\n\n// after: create the config in Composio first, or address it directly\nlet args = json!({\"action\": \"connect\", \"auth_config_id\": \"<id from the Composio dashboard>\"});","handlingStrategy":"validation","validationCode":"// Pre-check the same endpoint the tool uses before offering 'connect'\nlet resp = client\n    .get(\"https://backend.composio.dev/api/v3/auth_configs\")\n    .header(\"x-api-key\", api_key)\n    .query(&[(\"toolkit_slug\", app), (\"show_disabled\", \"true\")])\n    .send()\n    .await?;\nlet body: serde_json::Value = resp.json().await?;\nif body[\"items\"].as_array().map_or(true, |a| a.is_empty()) {\n    anyhow::bail!(\"no auth config for '{app}'; create one in Composio first\");\n}","typeGuard":null,"tryCatchPattern":"match tool.execute(json!({\"action\": \"connect\", \"app\": app})).await {\n    Ok(r) if r.success => { /* open redirect_url */ }\n    Ok(r) if r.error.clone().unwrap_or_default().contains(\"No auth config found\") => {\n        // route the user to Composio workspace setup instead of retrying\n    }\n    other => { /* other failures */ }\n}","preventionTips":["Create auth configs for every app you plan to connect before enabling connect in agent flows","Keep a per-environment checklist of toolkits with configs","Pass explicit auth_config_id in automated/CI environments"],"tags":["composio","rust","oauth","setup","connect"],"backgroundTag":"auth-config-not-found","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}