Skip to content

fix(gateway): feishu websocket monkey-patch breaks dingtalk and other platforms#20053

Closed
dawell wants to merge 1 commit into
NousResearch:mainfrom
dawell:fix/feishu-websocket-monkeypatch
Closed

fix(gateway): feishu websocket monkey-patch breaks dingtalk and other platforms#20053
dawell wants to merge 1 commit into
NousResearch:mainfrom
dawell:fix/feishu-websocket-monkeypatch

Conversation

@dawell

@dawell dawell commented May 5, 2026

Copy link
Copy Markdown

Bug

The feishu adapter monkey-patches websockets.connect globally:

websockets.connect = _connect_with_overrides

However, _connect_with_overrides was declared as async def, which returns a coroutine object instead of a context manager. Since Python modules are singletons, this replaces the global websockets.connect (a normal function returning a context manager) with a coroutine function.

Impact

Any other platform that imports websockets and uses async with websockets.connect(uri) will crash with:

TypeError: "coroutine" object does not support the asynchronous context manager protocol

Confirmed broken: dingtalk (dingtalk_stream uses async with websockets.connect(uri)).

Potentially affected: any future gateway platform or third-party library that shares the same websockets module instance.

Root Cause

# Before (broken) — returns coroutine, not context manager
async def _connect_with_overrides(*args, **kwargs):
    ...
    return await original_connect(*args, **kwargs)

The await unwraps the context manager into a coroutine, breaking the async with protocol for all consumers.

Fix

# After (fixed) — returns context manager, same as original connect()
def _connect_with_overrides(*args, **kwargs):
    ...
    return original_connect(*args, **kwargs)
  • async defdef: no longer a coroutine function
  • return await original_connect(...)return original_connect(...): returns the context manager object directly, preserving the original websockets.connect() interface
  • Override logic (ping_interval / ping_timeout injection) is unchanged

Testing

Verified compatible with websockets 13.x, 15.x, and 16.x. All three gateway platforms (feishu, dingtalk, weixin) connect normally after the fix.

The feishu adapter's _connect_with_overrides was declared as
'async def', which returns a coroutine object instead of a context
manager. Since Python modules are singletons, the monkey-patch
websockets.connect = _connect_with_overrides replaced the global
websockets.connect (a normal function returning a context manager)
with a coroutine function.

Other platforms that import websockets (e.g. dingtalk_stream using
'async with websockets.connect(uri)') would then get:

  TypeError: 'coroutine' object does not support the asynchronous
  context manager protocol

Fix: change 'async def _connect_with_overrides' to plain 'def', and
'return await original_connect(...)' to 'return original_connect(...)'.
This preserves the original connect() return type (context manager)
while still injecting ping_interval/ping_timeout overrides.

Compatible with websockets 13.x, 15.x, and 16.x.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/feishu Feishu / Lark adapter platform/dingtalk DingTalk adapter labels May 5, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #15986 and #17364 — same feishu websockets.connect monkey-patch issue. This PR fixes the async def → def conversion that #15986 attempted via local module copy.

@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #15986 and #17364 — same feishu websockets.connect monkey-patch issue.

@teknium1

Copy link
Copy Markdown
Contributor

This looks implemented on current main now by the same substantive fix. Automated hermes-sweeper review.

Evidence:

Thanks for the report and fix; the current main branch has the requested behavior.

@teknium1 teknium1 closed this Jun 11, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/dingtalk DingTalk adapter platform/feishu Feishu / Lark adapter sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants