Skip to content

fix(weixin): avoid cross-loop aiohttp session reuse in send_weixin_direct - #35237

Closed
betterMax wants to merge 1 commit into
NousResearch:mainfrom
betterMax:fix/weixin-cross-loop-session
Closed

fix(weixin): avoid cross-loop aiohttp session reuse in send_weixin_direct#35237
betterMax wants to merge 1 commit into
NousResearch:mainfrom
betterMax:fix/weixin-cross-loop-session

Conversation

@betterMax

Copy link
Copy Markdown

Bug

When the gateway is running, send_message tool calls to Weixin always fail with:

RuntimeError: Timeout context manager should be used inside a task

This affects both text and media delivery. Normal gateway replies work fine.

Root Cause

_run_async() (called by send_message_tool) detects a running event loop and spins up a new thread with asyncio.run(), creating a fresh event loop. However, send_weixin_direct() path A reuses the _LIVE_ADAPTERS aiohttp session, which is bound to the gateway's event loop. aiohttp raises RuntimeError when a session is used from a different loop than the one it was created on.

This explains the intermittent behavior:

  • ✅ Gateway normal replies → same loop → works
  • send_message tool → cross-loop conflict → fails
  • ✅ Gateway not running → CLI path, no cross-loop → works

Fix

Add a loop compatibility check before reusing the live adapter session. When loops differ, fall through to path B which creates a temporary session on the current loop.

current_loop = asyncio.get_running_loop()
session_loop = getattr(send_session, '_loop', None)
loop_compatible = session_loop is None or session_loop is current_loop
if live_adapter is not None and send_session is not None and not send_session.closed and loop_compatible:

Testing

File Type Size Result
.png image 400KB
.md document 2KB
.zip archive 652KB
.pdf document 552KB
Binary 1MB
Binary 5MB

…rect

When the gateway is running, _run_async() spins up a new thread with
a fresh event loop via asyncio.run(). The send_weixin_direct() path A
tries to reuse the live adapter's aiohttp session, but that session is
bound to the gateway's event loop. Using an aiohttp session from a
different loop triggers:

  RuntimeError: Timeout context manager should be used inside a task

This makes send_message tool calls from gateway context fail for both
text and media delivery, while normal gateway replies work fine.

Fix: check that the session's event loop matches the current loop
before attempting to reuse it. When loops differ, fall through to
path B which creates a temporary session on the current loop.

Tested: .png (400KB), .md (2KB), .zip (652KB), .pdf (552KB), 1MB and
5MB binary files all send successfully after the fix.
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/gateway Gateway runner, session dispatch, delivery platform/wecom WeCom / WeChat Work adapter duplicate This issue or pull request already exists labels May 30, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #12810 — the authoritative fix was already merged as #19141. At least 10 prior PRs addressed this same cross-event-loop aiohttp session reuse in send_weixin_direct(). See also #13520, #14384, #14481, #14873, #15911, #28835.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused cross-loop fix. This is already implemented on current main.

  • Automated hermes-sweeper review verified gateway/platforms/weixin.py:2307-2336: live adapter reuse requires send_session._loop is asyncio.get_running_loop(), and a mismatch falls through to a new aiohttp.ClientSession.
  • The same fix landed in a22465e07ab4b71019f711e7a6463f6590c50742 (fix(weixin): send_weixin_direct cross-loop session check) via merged PR fix(weixin): send_weixin_direct cross-loop session check #19141.
  • The merged commit is included in release v2026.5.7.
  • This matches the duplicate assessment already noted by @alt-glitch.

Closing as implemented on main.

@teknium1 teknium1 closed this Jul 13, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jul 13, 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 duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have platform/wecom WeCom / WeChat Work 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