Skip to content

fix(weixin): guard live_adapter session reuse against cross-loop calls#14873

Open
Mr-z-j wants to merge 1 commit into
NousResearch:mainfrom
Mr-z-j:fix/weixin-cross-loop-session-reuse
Open

fix(weixin): guard live_adapter session reuse against cross-loop calls#14873
Mr-z-j wants to merge 1 commit into
NousResearch:mainfrom
Mr-z-j:fix/weixin-cross-loop-session-reuse

Conversation

@Mr-z-j

@Mr-z-j Mr-z-j commented Apr 24, 2026

Copy link
Copy Markdown

Bug Description

When send_message is invoked from the gateway context (e.g., cron jobs or tool callbacks), _run_async spawns the coroutine in a fresh thread with a new event loop. Reusing the live_adapter's ClientSession (which was bound to the gateway's original event loop) causes aiohttp to raise:

Timeout context manager should be used inside a task

This prevents Weixin proactive message delivery from working reliably in gateway mode.

Root Cause

aiohttp.ClientSession is bound to the event loop that created it. In the current code (gateway/platforms/weixin.py), send_weixin_direct() unconditionally reuses live_adapter._send_session if it exists and is not closed, without checking whether the current running loop matches the session's bound loop.

Fix

Before reusing the live adapter's session, verify that send_session._loop matches asyncio.get_running_loop(). If the loops differ (cross-loop call), fall back to creating a new ClientSession.

Changes

  • gateway/platforms/weixin.py: added _session_loop / _current_loop check in send_weixin_direct()

Testing

  • Verified that proactive send_message to Weixin works from gateway context after the fix
  • Patch cleanly applies against origin/main (v0.11.0 + post-release commits)

Related

  • This is a production bugfix; no new dependencies or API changes.
  • Fixes Weixin proactive message delivery failures in multi-threaded gateway scenarios.

When send_message is invoked from the gateway context, _run_async
spawns the coroutine in a fresh thread with a new event loop.
Reusing the live_adapter's ClientSession (bound to the gateway's
loop) causes aiohttp to raise:

    Timeout context manager should be used inside a task

Fix: check that the session's bound event loop matches the current
running loop before reusing the live adapter. Falls back to creating
a new ClientSession when loops differ.
@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/wecom WeCom / WeChat Work adapter duplicate This issue or pull request already exists labels Apr 24, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #12810 — same root cause: cross-event-loop aiohttp session reuse in send_weixin_direct(). See also #14481, #13520, #14384 for prior attempts at the same fix.

@Mr-z-j

Mr-z-j commented Apr 24, 2026 via email

Copy link
Copy Markdown
Author

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 duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists platform/wecom WeCom / WeChat Work adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants