hermes - ✅(Solved) Fix [Bug] Weixin send_message fails with "Timeout context manager should be used inside a task" [1 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#17347Fetched 2026-04-30 06:48:13
View on GitHub
Comments
2
Participants
2
Timeline
8
Reactions
0
Author
Timeline (top)
labeled ×4commented ×2cross-referenced ×1subscribed ×1

Error Message

2026-04-29 16:18:30 ERROR [Weixin] send failed to=o9cq801z: Timeout context manager should be used inside a task

Root Cause

两种发送路径对比:

路径状态说明
普通对话回复(response ready → Send to weixin)✅ 正常走 session reply pipeline
send_message 工具 → 微信直接发送❌ 失败走独立发送路径

根本原因推断:send_message 的微信适配器代码中使用了 async with timeout() 等异步上下文管理器,但调用上下文不在合法的 asyncio task 中。普通对话回复走的是另一条代码路径,不触发此问题。

Fix Action

Fixed

PR fix notes

PR #17545: fix(weixin): route send_message media uploads through a fresh aiohttp session

Description (problem / solution / changelog)

Closes #17347.

Symptom

send_message tool call to a Weixin chat with a .docx / image attachment fails 5/5 times with:

WARNING [Weixin] send chunk failed to=…: Timeout context manager should be used inside a task
ERROR   [Weixin] send failed to=…: Timeout context manager should be used inside a task

Text replies through the same platform continue to work — only tool-initiated media sends break.

Root cause

send_weixin_direct (gateway/platforms/weixin.py:2005) optimistically reuses the live long-poll adapter's _send_session when that adapter is running:

live_adapter = _LIVE_ADAPTERS.get(resolved_token)
send_session = getattr(live_adapter, '_send_session', None)
if live_adapter is not None and send_session is not None and not send_session.closed:
    # reuse for text AND media

That _send_session was created inside the long-poll reader task. Reusing it from the tool-call task works for short request timeouts (the text-send path uses API_TIMEOUT_MS ≈ 8 s), but the 120-second upload-CDN timeout in _upload_ciphertext:

timeout = aiohttp.ClientTimeout(total=120)
async with session.post(upload_url, data=ciphertext,, timeout=timeout) as response:

trips aiohttp's asyncio.current_task() check inside the session's timeout handler when the session crosses task boundaries.

Text sends work because their timer registers and tears down within the same tool-call task turn; the 120 s upload timer spans enough turns that the task-binding check fails.

Fix

Reuse the live adapter only when media_files is empty. Any media send falls through to the existing fresh-session path (the same aiohttp.ClientSession that cron delivery and adapter-unavailable tool calls already use), so the upload runs in the tool-call task's own session and the timeout-context check sees a valid current task.

-if live_adapter is not None and send_session is not None and not send_session.closed:
+has_media = bool(media_files)
+if (
+    live_adapter is not None
+    and send_session is not None
+    and not send_session.closed
+    and not has_media
+):
     # text-only reuse, preserved to keep the common-case perf

Text-only behavior is preserved byte-for-byte. The adapter-unavailable branch (cron / standalone) already fell through to the fresh-session path, so its behavior also unchanged.

Not in scope

  • Doesn't restructure the live adapter's internal task model. That may be the right long-term fix (own task for each send op), but it's a bigger change and this one-line gate unblocks the user-visible bug first.
  • Doesn't add a regression test — the bug requires a live weixin account + CDN flight to reproduce. Adding a mock-aiohttp test that hits the same asyncio.current_task() branch is possible but significantly more scaffolding than the fix; happy to add in a follow-up if preferred.

File

  • gateway/platforms/weixin.py: +20 / -10

Changed files

  • gateway/platforms/weixin.py (modified, +20/-10)

Code Example

Timeout context manager should be used inside a task

---

2026-04-29 16:18:20 WARNING [Weixin] send chunk failed to=o9cq801z attempt=1/5: Timeout context manager should be used inside a task
2026-04-29 16:18:21 WARNING [Weixin] send chunk failed to=o9cq801z attempt=2/5: Timeout context manager should be used inside a task
2026-04-29 16:18:23 WARNING [Weixin] send chunk failed to=o9cq801z attempt=3/5: Timeout context manager should be used inside a task
2026-04-29 16:18:26 WARNING [Weixin] send chunk failed to=o9cq801z attempt=4/5: Timeout context manager should be used inside a task
2026-04-29 16:18:30 ERROR   [Weixin] send failed to=o9cq801z: Timeout context manager should be used inside a task
RAW_BUFFERClick to expand / collapse

Bug Description

在微信平台上调用 send_message 工具发送文件/媒体时,发送逻辑持续失败,报错:

Timeout context manager should be used inside a task

重试 5 次全部失败后消息彻底丢失。有趣的是,普通对话回复路径完全正常,只有 send_message 工具的文件发送路径触发此 bug。

Steps to Reproduce

  1. 在微信平台上使用 Hermes Agent
  2. 让 Agent 执行 send_message 工具发送带 MEDIA 附件的消息(如 .docx 文件)
  3. 观察网关日志

Expected Behavior

文件正常通过微信发送给用户。

Actual Behavior

2026-04-29 16:18:20 WARNING [Weixin] send chunk failed to=o9cq801z attempt=1/5: Timeout context manager should be used inside a task
2026-04-29 16:18:21 WARNING [Weixin] send chunk failed to=o9cq801z attempt=2/5: Timeout context manager should be used inside a task
2026-04-29 16:18:23 WARNING [Weixin] send chunk failed to=o9cq801z attempt=3/5: Timeout context manager should be used inside a task
2026-04-29 16:18:26 WARNING [Weixin] send chunk failed to=o9cq801z attempt=4/5: Timeout context manager should be used inside a task
2026-04-29 16:18:30 ERROR   [Weixin] send failed to=o9cq801z: Timeout context manager should be used inside a task

Analysis

两种发送路径对比:

路径状态说明
普通对话回复(response ready → Send to weixin)✅ 正常走 session reply pipeline
send_message 工具 → 微信直接发送❌ 失败走独立发送路径

根本原因推断:send_message 的微信适配器代码中使用了 async with timeout() 等异步上下文管理器,但调用上下文不在合法的 asyncio task 中。普通对话回复走的是另一条代码路径,不触发此问题。

Environment

  • OS: Deepin 23 (Linux 6.18.19-amd64-desktop-rolling)
  • Hermes Agent: latest (cnb.cool mirror)
  • Platform: Weixin (微信)
  • Python: 3.12

Related Log Evidence

同一次会话中,此问题反复出现(两次独立的 send_message 调用均失败):

  • 第一次:16:18:20-16:18:30(发送 .docx 需求说明书)
  • 第二次:16:18:35-16:18:45(重试同一文件)

而此前的正常文字对话响应全部成功送达(16:09, 16:19, 16:19 均有正常 reply)

extent analysis

TL;DR

Ensure that the send_message tool's Weixin adapter code uses asynchronous context managers within a valid asyncio task to resolve the timeout issue.

Guidance

  • Review the send_message tool's Weixin adapter code to identify where async with timeout() is used and ensure it's within an asyncio task.
  • Verify that the asyncio task is properly defined and executed to avoid the "Timeout context manager should be used inside a task" error.
  • Consider refactoring the code to use a higher-level abstraction that handles timeouts and asynchronous operations, if available.
  • Test the send_message tool with a simple message without media attachments to isolate if the issue is specific to media sending or a more general problem.

Example

No specific code example can be provided without the actual codebase, but ensuring that async with timeout() is used within an async def function or a task created with asyncio.create_task() is crucial.

Notes

The issue seems specific to the send_message tool's interaction with Weixin and the use of asynchronous context managers. The fact that ordinary conversation replies work normally suggests the problem is isolated to this specific code path.

Recommendation

Apply a workaround by modifying the send_message tool's Weixin adapter code to properly handle asynchronous operations and timeouts within a valid asyncio task, as the root cause analysis suggests this is the primary issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix [Bug] Weixin send_message fails with "Timeout context manager should be used inside a task" [1 pull requests, 2 comments, 2 participants]