-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Description
SDK Language
Python SDK (composio package)
SDK Version
composio==0.9.0
Runtime Environment
Python 3.11.9
Environment
Local Development
Describe the Bug
When executing the Dropbox tool DROPBOX_SEARCH_FILE_OR_FOLDER and passing the optional options parameter, the Composio Python SDK crashes with:
KeyError: 'type'
This happens inside the SDK, before the API request is sent.
Expected behavior:
The tool should execute normally and return search results, since options is an optional parameter.
Steps to Reproduce
- Initialize Composio Python SDK
- Connect a Dropbox account
- Call
DROPBOX_SEARCH_FILE_OR_FOLDERwithqueryandoptions - Observe SDK crash
Minimal Reproducible Example
from composio import Composio
composio = Composio(api_key="YOUR_API_KEY")
result = composio.tools.execute(
slug="DROPBOX_SEARCH_FILE_OR_FOLDER",
user_id="default",
connected_account_id="YOUR_CONNECTED_ACCOUNT_ID",
arguments={
"query": "Client Docs",
"options": {
"file_categories": ["folder"]
}
}
)Error Output / Stack Trace
KeyError: 'type'
File "composio/core/models/_files.py", line 235, in _substitute_file_uploads_recursively
if isinstance(request[_param], dict) and params[_param]["type"] == "object":
~~~~~~~~~~~~~~^^^^^^^^Reproducibility
- Always reproducible
- Intermittent / Sometimes
- Happened once, can’t reproduce
Additional Context or Screenshots
Root Cause (Analysis)
In composio/core/models/_files.py, the SDK assumes every parameter schema contains a top-level "type" field:
if isinstance(request[_param], dict) and params[_param]["type"] == "object":However, the Dropbox search tool defines options using anyOf:
"options": {
"anyOf": [
{ "type": "object", "properties": {...} },
{ "type": "null" }
]
}So params["options"] does not have "type", causing a KeyError.
Tool version pinning (e.g. 20260105_00) does not help, as the SDK uses the schema bundled inside the installed package.
Suggested Fix
Safely handle anyOf schemas instead of assuming "type" always exists, e.g.:
schema_def = params[_param]
is_object = (
schema_def.get("type") == "object"
or any(
s.get("type") == "object"
for s in schema_def.get("anyOf", [])
if isinstance(s, dict)
)
)