openclaw - ✅(Solved) Fix Discord attachment download hangs: missing readIdleTimeoutMs in fetchRemoteMedia [1 pull requests, 1 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
openclaw/openclaw#58528Fetched 2026-04-08 02:01:33
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
closed ×1cross-referenced ×1locked ×1

Root Cause

The Discord appendResolvedMediaFromAttachments function calls fetchRemoteMedia() without passing readIdleTimeoutMs, causing the download to block forever if the Discord CDN stalls or the connection idles.

Discord handler (auth-profiles-B5ypC5S-.js:199165):

const fetched = await fetchRemoteMedia({
    url: attachment.url,
    filePathHint: attachment.filename ?? attachment.url,
    maxBytes: params.maxBytes,
    fetchImpl: params.fetchImpl,
    ssrfPolicy: params.ssrfPolicy
    // ← readIdleTimeoutMs is MISSING
});

The same issue exists for sticker downloads at line 199235.

Compare with Telegram handler (auth-profiles-B5ypC5S-.js:130135), which correctly sets a timeout:

const TELEGRAM_DOWNLOAD_IDLE_TIMEOUT_MS = 30000; // 30s
// ...
readIdleTimeoutMs: TELEGRAM_DOWNLOAD_IDLE_TIMEOUT_MS

Without readIdleTimeoutMs, the internal readResponseWithLimit falls back to a raw reader.read() with no timeout — any CDN stall causes a permanent hang.

Fix Action

Fixed

PR fix notes

PR #58593: fix(discord): stop media downloads from hanging

Description (problem / solution / changelog)

Fixes #58528.

This PR fixes the Discord inbound media path so attachment and sticker downloads cannot hang indefinitely during message processing.

What changed

  • pass readIdleTimeoutMs into Discord attachment and sticker fetchRemoteMedia() calls
  • add Discord-specific idle and total media download timeout constants
  • propagate the inbound worker abortSignal into the media fetch path
  • keep existing fallback behavior so message text still delivers with placeholder media URLs when a download aborts, times out, or fails
  • add regression coverage for attachments, stickers, forwarded media, total-timeout fallback, and abort propagation

Why

Discord media downloads were still missing the body-read idle timeout in this path, and the inbound worker abort signal was not reaching the remote fetch. That left attachment processing exposed to hangs even when the worker itself was timing out.

Overlap

This supersedes the overlapping timeout-only approach in #58198 by carrying forward the timeout behavior and adding parent abort-signal propagation through the Discord monitor media resolution path.

Validation

  • pnpm install --frozen-lockfile
  • pnpm exec vitest run --config vitest.channels.config.ts extensions/discord/src/monitor/message-utils.test.ts
  • pnpm exec vitest run --config vitest.channels.config.ts extensions/discord/src/monitor/message-handler.process.test.ts
  • pnpm check currently fails on current main due to an unrelated existing lint error in src/agents/pi-embedded-runner/run/attempt.test.ts (resolveOllamaBaseUrlForRun imported but unused)

Changed files

  • extensions/discord/src/monitor/message-handler.process.ts (modified, +17/-6)
  • extensions/discord/src/monitor/message-utils.test.ts (modified, +209/-6)
  • extensions/discord/src/monitor/message-utils.ts (modified, +98/-12)
  • extensions/discord/src/monitor/timeouts.ts (modified, +2/-0)
  • src/agents/pi-embedded-runner/run/attempt.test.ts (modified, +0/-1)

Code Example

const fetched = await fetchRemoteMedia({
    url: attachment.url,
    filePathHint: attachment.filename ?? attachment.url,
    maxBytes: params.maxBytes,
    fetchImpl: params.fetchImpl,
    ssrfPolicy: params.ssrfPolicy
    // ← readIdleTimeoutMs is MISSING
});

---

const TELEGRAM_DOWNLOAD_IDLE_TIMEOUT_MS = 30000; // 30s
// ...
readIdleTimeoutMs: TELEGRAM_DOWNLOAD_IDLE_TIMEOUT_MS
RAW_BUFFERClick to expand / collapse

Bug Description

When sending a Discord message with an image attachment to an OpenClaw agent, the message processing hangs indefinitely. The agent becomes unresponsive and never replies.

Root Cause

The Discord appendResolvedMediaFromAttachments function calls fetchRemoteMedia() without passing readIdleTimeoutMs, causing the download to block forever if the Discord CDN stalls or the connection idles.

Discord handler (auth-profiles-B5ypC5S-.js:199165):

const fetched = await fetchRemoteMedia({
    url: attachment.url,
    filePathHint: attachment.filename ?? attachment.url,
    maxBytes: params.maxBytes,
    fetchImpl: params.fetchImpl,
    ssrfPolicy: params.ssrfPolicy
    // ← readIdleTimeoutMs is MISSING
});

The same issue exists for sticker downloads at line 199235.

Compare with Telegram handler (auth-profiles-B5ypC5S-.js:130135), which correctly sets a timeout:

const TELEGRAM_DOWNLOAD_IDLE_TIMEOUT_MS = 30000; // 30s
// ...
readIdleTimeoutMs: TELEGRAM_DOWNLOAD_IDLE_TIMEOUT_MS

Without readIdleTimeoutMs, the internal readResponseWithLimit falls back to a raw reader.read() with no timeout — any CDN stall causes a permanent hang.

Additional Issue

The abortSignal from processDiscordInboundJob (the overall task timeout) is available in processDiscordMessage context but is never propagated to resolveMediaList or its child fetchRemoteMedia calls. This means even the parent task timeout cannot cancel a stuck media download.

Expected Behavior

Discord attachment downloads should have an idle timeout (e.g., 30s like Telegram) and respect the parent task's abort signal.

Suggested Fix

  1. Add a DISCORD_DOWNLOAD_IDLE_TIMEOUT_MS constant (e.g., 30000)
  2. Pass readIdleTimeoutMs to both fetchRemoteMedia calls in appendResolvedMediaFromAttachments and appendResolvedMediaFromStickers
  3. Propagate abortSignal from processDiscordMessage through resolveMediaList to fetchRemoteMedia

Environment

  • OpenClaw version: 2026.3.28 (f9b1079)
  • Platform: macOS (Darwin 25.3.0, arm64)
  • Channel: Discord
  • Model: claude-opus-4-6 (vision-capable, so image understanding is skipped — hang is in the download phase)

extent analysis

TL;DR

Add a readIdleTimeoutMs parameter to fetchRemoteMedia calls and propagate the abortSignal to prevent indefinite hangs during Discord attachment downloads.

Guidance

  • Define a DISCORD_DOWNLOAD_IDLE_TIMEOUT_MS constant (e.g., 30000) to set a reasonable idle timeout for Discord attachment downloads.
  • Update the fetchRemoteMedia calls in appendResolvedMediaFromAttachments and appendResolvedMediaFromStickers to include the readIdleTimeoutMs parameter.
  • Modify the resolveMediaList function to accept and propagate the abortSignal from processDiscordMessage to fetchRemoteMedia calls, ensuring that stuck downloads can be cancelled.

Example

const DISCORD_DOWNLOAD_IDLE_TIMEOUT_MS = 30000;
// ...
const fetched = await fetchRemoteMedia({
    url: attachment.url,
    filePathHint: attachment.filename ?? attachment.url,
    maxBytes: params.maxBytes,
    fetchImpl: params.fetchImpl,
    ssrfPolicy: params.ssrfPolicy,
    readIdleTimeoutMs: DISCORD_DOWNLOAD_IDLE_TIMEOUT_MS,
    signal: abortSignal // propagate the abort signal
});

Notes

The suggested fix assumes that the abortSignal is properly implemented and propagated through the processDiscordMessage and resolveMediaList functions. Additionally, the choice of DISCORD_DOWNLOAD_IDLE_TIMEOUT_MS value may need to be adjusted based on specific requirements or constraints.

Recommendation

Apply the workaround by adding the readIdleTimeoutMs parameter and propagating the abortSignal to prevent indefinite hangs during Discord attachment downloads. This approach addresses the root cause of the issue and provides a more robust solution.

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

openclaw - ✅(Solved) Fix Discord attachment download hangs: missing readIdleTimeoutMs in fetchRemoteMedia [1 pull requests, 1 participants]