Skip to content

fix(feishu): avoid global websockets monkey-patching to prevent DingTalk conflict#15986

Closed
qianweicheng wants to merge 1 commit into
NousResearch:mainfrom
qianweicheng:fix/feishu-dingtalk-websocket-conflict
Closed

fix(feishu): avoid global websockets monkey-patching to prevent DingTalk conflict#15986
qianweicheng wants to merge 1 commit into
NousResearch:mainfrom
qianweicheng:fix/feishu-dingtalk-websocket-conflict

Conversation

@qianweicheng

Copy link
Copy Markdown

Problem

The Feishu platform adapter was monkey-patching websockets.connect globally in _run_official_feishu_ws_client. This caused issues when running multiple platforms simultaneously — specifically, DingTalk (which also uses websockets) would break because its connection logic was being overridden by Feishu's custom overrides.

Solution

Instead of patching the global websockets module, create a local module copy for the Feishu WS client:

  1. Use types.ModuleType to create a local websockets module copy
  2. Copy all attributes from the original module
  3. Apply _connect_with_overrides only on the local copy
  4. Assign the local copy to ws_client_module.websockets
  5. In the finally block, restore the original module reference

Changes

  • gateway/platforms/feishu.py: Modified _run_official_feishu_ws_client to use local module copy instead of global monkey-patching

Testing

  • Feishu websocket connection still works as expected
  • DingTalk can now run concurrently without websocket conflicts

Impact

This is a minimal, non-breaking change that enables multi-platform deployments where Feishu and DingTalk (or other websocket-using platforms) need to coexist.

…alk conflict

The Feishu platform adapter was monkey-patching websockets.connect globally,
which broke other platforms (e.g., DingTalk) that also use websockets.

Changes:
- Create a local copy of the websockets module for Feishu WS client
- Apply connection overrides only on the local copy
- Restore the original module reference in finally block

This allows Feishu and DingTalk (and potentially other platforms) to coexist
without interfering with each other's websocket connections.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists platform/feishu Feishu / Lark adapter platform/dingtalk DingTalk adapter comp/gateway Gateway runner, session dispatch, delivery labels Apr 26, 2026
@teknium1

teknium1 commented May 4, 2026

Copy link
Copy Markdown
Contributor

The intent of this PR (stop globally monkey-patching websockets.connect so it doesn't break DingTalk and other websocket-using platforms) is valid, but the implementation has a bug: the restore path uses ws_client_module.websockets.__dict__.get('__original_module__', ws_client_module.websockets), but nothing ever sets __original_module__ on the local copy. That means the restore is effectively a no-op and the local-module-object swap leaks.

Closing this PR so it doesn't land as-is. If you want to pursue the fix, the cleaner shape is: use contextlib / try-finally around the specific call site that needs the overridden connect, rather than touching module state at all. Happy to take a follow-up PR in that shape. Thanks for catching the cross-platform interference!

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 type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants