Composio SDK & API Workarounds
1. Routing NO_AUTH tools via V3.1 Endpoints (SDK 0.5.39)
At the time of writing (SDK composio-core@0.5.39), calling generic endpoints using entity.execute() for some NO_AUTH apps (specifically gemini) will result in a masked validation error:
400 Bad Request - Validation Errors: undefined
Or from the raw backend generic action endpoints (v2/actions/.../execute):
App name and entity id must be present, if connected account id is not specified.
Root Cause:
The standard backend action router demands routing variables (connectedAccountId OR appName + entityId) in the payload envelope. For tools that are purely NO_AUTH (like Gemini Flash Image Generator), this causes validation failure since the SDK omits necessary fallback routing context.
Solution:
Bypass the SDK's entity.execute() generic path entirely and hit the v3.1 Tool Slug Execute endpoint directly via fetch/axios with API keys in the header.
V3.1 Endpoint structure
POST https://backend.composio.dev/api/v3.1/tools/execute/{tool_slug}
Payload format:
{
"arguments": {
"prompt": "value...",
"model": "value...",
"aspect_ratio": "value..."
}
}
Headers:
{
"content-type": "application/json",
"x-api-key": "COMPOSIO_API_KEY_HERE"
}
TypeScript Adapter Implementation
Place this helper in your initialization file (e.g. src/lib/composio/client.ts) to transparently override the faulty routes.
type V31ToolExecuteResult = any;
async function executeViaV31ToolSlug(args: {
apiKey: string;
baseURL: string;
tool_slug: string;
arguments: Record<string, any>;
}): Promise`<V31ToolExecuteResult>` {
const url = `${args.baseURL.replace(/\/$/, "")}/api/v3.1/tools/execute/${encodeURIComponent(args.tool_slug)}`;
const res = await fetch(url, {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": args.apiKey,
},
body: JSON.stringify({
arguments: args.arguments,
}),
});
const text = await res.text();
let json: any;
try { json = JSON.parse(text); } catch { throw new Error(`Non-JSON response (${res.status}): ${text}`); }
if (!res.ok) {
throw new Error(`V3.1 tool execute failed (${res.status}): ${JSON.stringify(json)}`);
}
return json;
}
// Inside your main executor:
export async function executeComposioAction(actionName: string, params: Record<string, any>) {
if (actionName.startsWith("GEMINI_")) {
return await executeViaV31ToolSlug({
apiKey: process.env.COMPOSIO_API_KEY,
baseURL: process.env.COMPOSIO_BASE_URL,
tool_slug: actionName,
arguments: params,
});
}
// existing SDK execute for other tools...
}
2. Tested & Verified Scripts
The validation test for GEMINI_GENERATE_IMAGE is stored at tmp/test-gemini-v31.ts. Run it via bun run tmp/test-gemini-v31.ts to ensure your backend keys are valid and the REST bypass works smoothly.
