openclaw - ✅(Solved) Fix Media attachments broken: channel-outbound-send.ts always calls sendText, never sendMedia [2 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
openclaw/openclaw#62884Fetched 2026-04-09 08:01:14
View on GitHub
Comments
2
Participants
2
Timeline
15
Reactions
0
Author
Participants
Timeline (top)
referenced ×7commented ×2cross-referenced ×2mentioned ×2

Root Cause

src/cli/send-runtime/channel-outbound-send.ts introduced in ab96520bba (refactor(plugins): move channel behavior into plugins, Apr 3) always calls outbound.sendText() even when opts.mediaUrl is present. It never calls outbound.sendMedia().

// channel-outbound-send.ts line 29 — always sendText
return await outbound.sendText({
  cfg: opts.cfg ?? loadConfig(),
  to,
  text,
  mediaUrl: opts.mediaUrl,  // passed but ignored by sendText adapters
  ...
});

The sendText adapter for most channels (including WhatsApp) ignores mediaUrl — only sendMedia handles it.

Fix Action

Fix

When opts.mediaUrl is present and the adapter implements sendMedia, call sendMedia instead of sendText:

if (opts.mediaUrl && outbound.sendMedia) {
  return await outbound.sendMedia({
    ...sharedCtx,
    mediaUrl: opts.mediaUrl,
    mediaLocalRoots: opts.mediaLocalRoots,
  });
}
return await outbound.sendText(sharedCtx);

PR fix notes

PR #62889: fix(outbound): route media sends to sendMedia instead of sendText

Description (problem / solution / changelog)

Summary

  • channel-outbound-send.ts always called outbound.sendText() even when mediaUrl was present, silently dropping all media attachments (images, PDFs, documents)
  • When opts.mediaUrl is set and the adapter implements sendMedia, now calls sendMedia instead

Test plan

  • openclaw message send --media <image-url> --message "test" delivers image as attachment (not text-only)
  • openclaw message send --media <pdf-url> --message "test" delivers PDF as document attachment
  • openclaw message send --message "text only" still works (no media path)
  • Agent message tool with media parameter sends attachment via WhatsApp

Fixes #62884

🤖 Generated with Claude Code

Changed files

  • src/cli/send-runtime/channel-outbound-send.ts (modified, +12/-5)

PR #62896: fix(cli): route to sendMedia when mediaUrl is present in CLI runtime send

Description (problem / solution / changelog)

Summary

Fixes #62884 — Media attachments (images, PDFs, documents) sent via the CLI message send --media or the agent message tool with media parameter were silently dropped as text-only.

Root cause

channel-outbound-send.ts always called sendText(), whose adapters ignore the mediaUrl field. Only sendMedia handles attachments.

The CLI runtime path through createChannelOutboundRuntimeSend was passing mediaUrl to sendText, which discarded it.

Changes

  • Extract shared context into sharedCtx (cfg, to, text, accountId, threadId, replyToId, silent, forceDocument, gifPlayback, gatewayClientScopes)
  • When opts.mediaUrl is set AND the adapter implements sendMedia, call sendMedia instead
  • Fall back to sendText otherwise (preserves behavior for channels without a sendMedia implementation)

Testing

pnpm test:cli (vitest.cli.config.ts): 3 passing tests

  • calls sendText when no mediaUrl is provided
  • calls sendMedia when mediaUrl is provided and sendMedia exists
  • falls back to sendText when mediaUrl is set but sendMedia does not exist

Changed files

  • src/cli/send-runtime/channel-outbound-send.test.ts (added, +77/-0)
  • src/cli/send-runtime/channel-outbound-send.ts (modified, +6/-3)

Code Example

// channel-outbound-send.ts line 29 — always sendText
return await outbound.sendText({
  cfg: opts.cfg ?? loadConfig(),
  to,
  text,
  mediaUrl: opts.mediaUrl,  // passed but ignored by sendText adapters
  ...
});

---

if (opts.mediaUrl && outbound.sendMedia) {
  return await outbound.sendMedia({
    ...sharedCtx,
    mediaUrl: opts.mediaUrl,
    mediaLocalRoots: opts.mediaLocalRoots,
  });
}
return await outbound.sendText(sharedCtx);
RAW_BUFFERClick to expand / collapse

Bug

Media attachments (images, PDFs, documents) sent via the CLI message send --media or via the agent message tool with media parameter are silently dropped. The message is delivered as text-only — no attachment reaches the recipient.

Root cause

src/cli/send-runtime/channel-outbound-send.ts introduced in ab96520bba (refactor(plugins): move channel behavior into plugins, Apr 3) always calls outbound.sendText() even when opts.mediaUrl is present. It never calls outbound.sendMedia().

// channel-outbound-send.ts line 29 — always sendText
return await outbound.sendText({
  cfg: opts.cfg ?? loadConfig(),
  to,
  text,
  mediaUrl: opts.mediaUrl,  // passed but ignored by sendText adapters
  ...
});

The sendText adapter for most channels (including WhatsApp) ignores mediaUrl — only sendMedia handles it.

Impact

  • openclaw message send --media <url> sends text-only, no attachment
  • Agent message tool with media parameter sends text-only
  • All channels using the deliveryMode: "gateway" path through CLI deps are affected
  • The gateway WS handler path (deliverOutboundPayloads) is NOT affected — it correctly routes to sendMedia when media is present

Fix

When opts.mediaUrl is present and the adapter implements sendMedia, call sendMedia instead of sendText:

if (opts.mediaUrl && outbound.sendMedia) {
  return await outbound.sendMedia({
    ...sharedCtx,
    mediaUrl: opts.mediaUrl,
    mediaLocalRoots: opts.mediaLocalRoots,
  });
}
return await outbound.sendText(sharedCtx);

Introduced in

Commit ab96520bba — refactor(plugins): move channel behavior into plugins (Apr 3, 2026)

extent analysis

TL;DR

To fix the issue with media attachments being silently dropped, modify the channel-outbound-send.ts file to call outbound.sendMedia() when opts.mediaUrl is present and the adapter implements sendMedia.

Guidance

  • Verify that the outbound object has a sendMedia method before calling it to avoid potential errors.
  • Update the channel-outbound-send.ts file to use the proposed fix, which checks for the presence of opts.mediaUrl and the sendMedia method on the outbound object.
  • Test the updated code with different adapters and channels to ensure that media attachments are being sent correctly.
  • Review the commit history to ensure that the fix is applied to the correct version of the codebase, specifically the version introduced in commit ab96520bba.

Example

if (opts.mediaUrl && outbound.sendMedia) {
  return await outbound.sendMedia({
    ...sharedCtx,
    mediaUrl: opts.mediaUrl,
    mediaLocalRoots: opts.mediaLocalRoots,
  });
}
return await outbound.sendText(sharedCtx);

Notes

This fix assumes that the sendMedia method is implemented correctly on the adapters that support it. If issues persist, further debugging may be necessary to identify the root cause.

Recommendation

Apply the workaround by modifying the channel-outbound-send.ts file to call outbound.sendMedia() when opts.mediaUrl is present, as this directly addresses the identified issue and should resolve the problem with media attachments being silently dropped.

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