[Bug]: Zoom webinar creation fails — managed OAuth app can't request webinar:write scope
SDK Language
Python SDK (composio package)
SDK Version
composio==0.15.0, composio-client==1.39.0, composio-langgraph==0.15.0 (issue reproduces via hosted Tool Router meta-tools, not SDK-specific)
Runtime Environment
Python 3.11.9, Linux (server-side agent backend using langgraph + Tool Router meta-tools); bug is platform-side (managed Zoom OAuth app scopes + toolkit coverage)
Environment
Production Deployment
Describe the Bug
An end user asked our agent (via Tool Router meta-tools) to create a Zoom webinar. The flow is unfixable from the user side, for three compounding reasons:
The managed Zoom OAuth app cannot request webinar creation.
GET /api/v3/toolkits/zoom→composio_managed_auth[0].scopes.availablelists 26 scopes; every webinar scope is read-only exceptwebinar:write:registrant.webinar:write:webinar(and update/delete) are not registered on the app, so no auth config and no re-consent can ever request them.The Zoom toolkit ships no webinar-creation tool (17 tools; webinar coverage is only ADD_A_WEBINAR_REGISTRANT / GET_A_WEBINAR / LIST_WEBINARS / LIST_WEBINAR_PARTICIPANTS). Yet COMPOSIO_SEARCH_TOOLS answers webinar-creation use cases with adjacent tools as
primary_tool_slugs(ZOOM_ADD_A_WEBINAR_REGISTRANT, thenZOOM_CREATE_A_MEETING— a meeting, not a webinar) instead of flagging the capability gap.COMPOSIO_REMOTE_WORKBENCH's
proxy_executeoffers raw Zoom API access on that same managed auth, so the agent reasonably fell back toPOST /users/me/webinars— and Zoom rejected it with a scope error the platform can never satisfy. Nothing distinguishes "scope not granted (re-consent may fix)" from "scope not requestable by this app (re-consent cannot fix)", so the agent looped on MANAGE_CONNECTIONS reinitiate and the end user completed a real OAuth consent, approved every scope offered, and got the identical error. Their (accurate) report: "I gave all permissions that were asked for but we still don't seem to have the right permission."
Expected: either webinar creation is supported end-to-end (scope registered + tool available), or the platform surfaces (search, workbench, connection manager) tell the agent the operation is unsupported instead of routing it into an OAuth loop that cannot succeed.
Note also the half-surface inconsistency: the app requests webinar:write:registrant and ships ADD_A_WEBINAR_REGISTRANT, but registrants can only be added to webinars the connected account cannot create through Composio.
Steps to Reproduce
All inside one Tool Router session (agentic flow; customer values masked):
COMPOSIO_SEARCH_TOOLSwith use case "Create and configure a Zoom webinar event with attendee registration for a product launch" → returnsprimary_tool_slugs: ["ZOOM_ADD_A_WEBINAR_REGISTRANT"], relatedZOOM_GET_A_WEBINAR,ZOOM_LIST_WEBINARS. A follow-up query "Create a new Zoom webinar with registration enabled and configure its title, description, date, duration, timezone, and approval settings" →primary_tool_slugs: ["ZOOM_CREATE_A_MEETING"]. Neither response signals that webinar creation is unsupported.COMPOSIO_MANAGE_CONNECTIONS(toolkits: ["zoom"]) → managed auth config is auto-created, end user completes the hosted OAuth flow and approves the full consent screen → connection ACTIVE.- Agent falls back to
COMPOSIO_REMOTE_WORKBENCH→proxy_execute("POST", "/users/me/webinars", "zoom", body={...})(see minimal example) → Zoom returns the 400 scope error below. COMPOSIO_MANAGE_CONNECTIONSwithreinitiate_all: true→ "All connections are active" (was_reinitiated: false); retry of step 3 → byte-identical 400. The loop cannot converge: re-consent can only offer scopes the managed app registers.- Root-cause check:
GET /api/v3/toolkits/zoom→composio_managed_auth[0].scopes.availablecontains nowebinar:write:webinar/webinar:update:webinar/webinar:delete:webinar(only webinar read scopes +webinar:write:registrant), and the connected account's grantedscopestring exactly equals the auth config's requested list — the user withheld nothing.
Minimal Reproducible Example
# Executed inside COMPOSIO_REMOTE_WORKBENCH (customer strings masked)
payload = {
"topic": "<masked webinar title>",
"type": 5,
"start_time": "2026-09-10T11:00:00",
"duration": 60,
"timezone": "America/Los_Angeles",
"agenda": "<masked>",
"settings": {
"host_video": True,
"panelists_video": True,
"practice_session": True,
"approval_type": 0,
"registration_type": 1,
"audio": "both",
"auto_recording": "cloud",
"question_and_answer": {"enable": True, "allow_anonymous_questions": True},
},
}
result, error = proxy_execute("POST", "/users/me/webinars", "zoom", body=payload)
Proof it can never succeed with the managed app:
curl -s -H "x-api-key: $COMPOSIO_API_KEY" https://backend.composio.dev/api/v3/toolkits/zoom \
| jq '.composio_managed_auth[0].scopes.available | map(select(contains("webinar")))'
# ["webinar:read:webinar", "webinar:read:list_registrants", "webinar:read:list_webinars",
# "webinar:read:list_past_participants", "webinar:read:participant", "webinar:write:registrant"]Error Output / Stack Trace
COMPOSIO_REMOTE_WORKBENCH result (stdout), verbatim:
Helper Function Error:Bad Request Error:proxy_execute:API returned status 400: Invalid access token, does not contain scopes:[webinar:write:webinar, webinar:write:webinar:admin].
{'error': 'API returned status 400: Invalid access token, does not contain scopes:[webinar:write:webinar, webinar:write:webinar:admin].'}
Secondary papercut: a first attempt used the documented Zoom path prefix and got a 404 from the proxy:
Helper Function Error:Not Found Error:proxy_execute:API returned status 404: This API endpoint is not recognized.
(call was proxy_execute("POST", "/v2/users/me/webinars", "zoom", ...) — the proxy wants paths without the /v2 prefix, which isn't documented in the workbench guidance)Reproducibility
- Always reproducible
- Intermittent / Sometimes
- Happened once, can’t reproduce
Additional Context or Screenshots
Identifiers for your logs (Composio-side only, happy to share more privately):
- Auth config:
ac_vQWJvXTaoo3_(Composio-managed OAUTH2, auto-created by the Tool Router session) - Connected account:
ca_9iWNGz05KNxL(status ACTIVE; granted scope string == requested list) - Tool Router session id:
farm; occurred ~2026-08-20 17:56–18:01 UTC
Requested fixes, in order of value:
- Register
webinar:write:webinar,webinar:update:webinar,webinar:delete:webinaron the managed Zoom app and add them to the toolkit's available scopes. - Ship first-class webinar CRUD tools (e.g.
ZOOM_CREATE_A_WEBINAR) — the toolkit currently has ADD_A_WEBINAR_REGISTRANT but no way to create the webinar it registers people into. - Make
COMPOSIO_SEARCH_TOOLSsay when a use case is unsupported by a toolkit instead of returning adjacent tools asprimary_tool_slugs(here: a registrant tool, then a meeting tool, for a webinar-creation query). - Have
proxy_execute/MANAGE_CONNECTIONSdistinguish "scope not granted (re-consent may fix)" from "scope not requestable by this app (re-consent cannot fix)" — e.g. compare the scope named in the provider error against the managed app's available scopes and annotate the result. This is what turns a capability gap into an end-user OAuth loop today.
Zoom-side note for anyone hitting this: even with the scope, POST /users/me/webinars also requires the connected Zoom user to be Licensed with the Webinar add-on (Basic accounts get a plan error) — worth mentioning in the tool/toolkit docs once creation is supported.
Source: ComposioHQ/composio