openclaw - ✅(Solved) Fix [Bug]: `message send --media` routes .mp4 through sendVideo and `--force-document` does not override [2 pull requests, 3 comments, 4 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#80389Fetched 2026-05-11 03:15:13
View on GitHub
Comments
3
Participants
4
Timeline
11
Reactions
2
Timeline (top)
commented ×3mentioned ×3subscribed ×3cross-referenced ×2

openclaw message send --channel telegram --target <chat> --media <file.mp4> routes MP4 files through Telegram's sendVideo endpoint, which fails with Network request for 'sendVideo' failed! (no further detail). The documented --force-document flag, intended to "send media as document to avoid Telegram compression," does not override the routing — the same sendVideo call is made and the same error returned.

The result is that no video file can be delivered to Telegram via message send regardless of flags, and the agent CLI returns exit 0 with the failure only visible in stderr lines, so callers (scripts, agents) think the send succeeded.

Error Message

[telegram] video failed: Network request for 'sendVideo' failed! HttpError: Network request for 'sendVideo' failed!

Root Cause

Video delivery is a common request (downloaded YouTube/X videos, screen recordings, generated content). The current state means any agent skill that downloads a video and tries to deliver it via message send --media silently fails, and the agent has no way to detect this without scraping stderr.

Related: #74061 (<final>MEDIA:... regression in 2026.4.26+) is a different code path with the same outward symptom ("Media failed"). Fixing this --media bug doesn't fix #74061 and vice versa.

Fix Action

Workaround

Bypass the plugin and POST directly to Telegram's bot API with sendDocument — works first try, in seconds, and Telegram still renders an inline video player for MP4s. So the underlying network and bot setup are fine; it's specifically the plugin's routing.

TOKEN=$(jq -r '.channels.telegram.botToken' /path/to/openclaw.json)
curl -s -F chat_id=<chat> -F document=@/path/file.mp4 \
  "https://api.telegram.org/bot${TOKEN}/sendDocument"
# → {"ok": true, "result": {"message_id": ..., "video": {...}}}

PR fix notes

PR #80400: [AI-assisted] fix(telegram): force document video media

Description (problem / solution / changelog)

## Summary

  • Route Telegram video media through sendDocument when callers set forceDocument / --force-document, instead of reaching the sendVideo branch first.
  • Skip video-dimension probing for forced document sends because Telegram document uploads do not use video width/height params.
  • Update CLI help, message-tool schema text, docs, prompt snapshots, and the changelog so the public contract includes videos.

Fixes #80389.

Real behavior proof

Behavior or issue addressed: Telegram message send --media <file.mp4> --force-document had a source-proven routing bug where video/mp4 still selected sendVideo; the explicit document override now selects sendDocument.

Real environment tested: Local Windows checkout C:\oc80389, Node v24.13.0, pnpm 10.33.2, rebased on openclaw/openclaw:main at ed2c3a9b9d. I ran the production Telegram sendMessageTelegram entrypoint from Node with a redacted token and a local MP4 fixture; the outbound API object recorded the selected Telegram method without sending to the external Telegram service.

Exact steps or command run after this patch:

$proof = Join-Path $env:TEMP "openclaw-force-document-proof.mp4"
[IO.File]::WriteAllBytes($proof, [byte[]](0,0,0,24,102,116,121,112,109,112,52,50,0,0,0,0,109,112,52,50,105,115,111,109))
node --import tsx --input-type=module -e "<invoke sendMessageTelegram('123456', 'forced document proof', { cfg: {}, token: 'redacted-token', mediaUrl: $proof, mediaLocalRoots: [process.env.TEMP], forceDocument: true, api: recorder })>" $proof
Remove-Item -LiteralPath $proof

Evidence after fix: Terminal output from the production send entrypoint command:

{
  "result": {
    "messageId": "202",
    "chatId": "123456"
  },
  "calls": [
    {
      "method": "sendDocument",
      "chatId": "123456",
      "caption": "forced document proof",
      "parse_mode": "HTML",
      "disable_content_type_detection": true,
      "fileClass": "InputFile"
    }
  ]
}

Observed result after fix: The only outbound media method recorded was sendDocument, with disable_content_type_detection: true; no sendVideo, sendVideoNote, sendAnimation, or sendPhoto call appeared.

What was not tested: No live Telegram Bot API upload was run from this machine. Automatic fallback from a failed sendVideo to sendDocument is intentionally out of scope because ClawSweeper called out duplicate-send risk for ambiguous network failures. The repository's focused automated coverage remains supplemental.

Verification

  • corepack pnpm test extensions/telegram/src/send.test.ts src/cli/program/message/helpers.test.ts src/agents/tools/message-tool.test.ts
  • corepack pnpm run tsgo:extensions:test
  • corepack pnpm exec oxfmt --check --threads=1 ...changed files...
  • corepack pnpm check:changed
  • git diff --check origin/main...HEAD
  • codex review --base origin/main -c model_reasoning_effort='"medium"'

AI-assisted; I reviewed the diff and understand the change.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • docs/channels/telegram.md (modified, +1/-1)
  • docs/cli/message.md (modified, +1/-1)
  • extensions/telegram/src/send.test.ts (modified, +37/-0)
  • extensions/telegram/src/send.ts (modified, +5/-3)
  • src/agents/tools/message-tool.ts (modified, +3/-2)
  • src/cli/program/message/register.send.ts (modified, +1/-1)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.discord-group.json (modified, +2/-2)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.heartbeat-turn.json (modified, +2/-2)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.telegram-direct.json (modified, +2/-2)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/discord-group-codex-message-tool.md (modified, +2/-2)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-direct-codex-message-tool.md (modified, +2/-2)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-heartbeat-codex-tool.md (modified, +2/-2)

PR #80405: fix(telegram): honor force document for videos

Description (problem / solution / changelog)

Summary

  • route Telegram video media through sendDocument when --force-document is set
  • skip video dimension probing and sendVideo/sendVideoNote selection in forced document mode
  • update forceDocument docs/tool descriptions to include videos

Fixes #80389

Real behavior proof

Behavior or issue addressed: Telegram video media sent with --force-document / forceDocument: true should route through Telegram sendDocument, not sendVideo, so Telegram does not apply video compression or reject the upload as a typed video.

Real environment tested: Local OpenClaw checkout on macOS, branch fix/80389-telegram-force-document-video, Node/tsx runtime, FFmpeg 8.0.1, OpenClaw Telegram sendMessageTelegram runtime path. The Telegram API object was overridden to capture the outgoing method and params without sending to an external chat.

Exact steps or command run after this patch:

ffmpeg -y -f lavfi -i color=c=black:s=16x16:d=0.2 -pix_fmt yuv420p /tmp/openclaw-force-document-proof.mp4

node --import tsx --eval '
import { sendMessageTelegram } from "./extensions/telegram/src/send.ts";
const calls = [];
const api = {
  sendDocument: async (chatId, file, params) => {
    calls.push({ method: "sendDocument", chatId, params });
    return { message_id: 777, chat: { id: chatId } };
  },
  sendVideo: async (chatId, file, params) => {
    calls.push({ method: "sendVideo", chatId, params });
    return { message_id: 778, chat: { id: chatId } };
  },
  sendPhoto: async (chatId, file, params) => {
    calls.push({ method: "sendPhoto", chatId, params });
    return { message_id: 779, chat: { id: chatId } };
  },
  sendAnimation: async (chatId, file, params) => {
    calls.push({ method: "sendAnimation", chatId, params });
    return { message_id: 780, chat: { id: chatId } };
  },
};
const cfg = { channels: { telegram: { botToken: "123456:TEST" } } };
const result = await sendMessageTelegram("12345", "forced video proof", {
  cfg,
  token: "123456:TEST",
  mediaUrl: "/tmp/openclaw-force-document-proof.mp4",
  mediaLocalRoots: ["/tmp"],
  forceDocument: true,
  api,
});
console.log(JSON.stringify({ result, calls }, null, 2));
'

Evidence after fix: Terminal output from the after-fix command:

{
  "result": {
    "messageId": "777",
    "chatId": "12345"
  },
  "calls": [
    {
      "method": "sendDocument",
      "chatId": "12345",
      "params": {
        "caption": "forced video proof",
        "parse_mode": "HTML",
        "disable_content_type_detection": true
      }
    }
  ]
}

Observed result after fix: The .mp4 send returned messageId: "777" and produced exactly one captured Telegram API call: sendDocument with disable_content_type_detection: true. There was no sendVideo call in the captured output.

What was not tested: I did not perform a live send to Telegram servers with real bot/chat credentials; the command above proves the local OpenClaw runtime route and Telegram method selection without external delivery.

Tests

  • pnpm protocol:check
  • pnpm prompt:snapshots:check
  • pnpm test extensions/telegram/src/send.test.ts src/cli/program/message/helpers.test.ts
  • git diff --check

Notes

  • pnpm check:changed reaches an unrelated existing extension-test typecheck failure in extensions/discord/src/internal/interactions.test.ts about customId/values on the timed-out union branch; the focused Telegram/CLI tests pass.

Changed files

  • apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift (modified, +4/-0)
  • docs/channels/telegram.md (modified, +1/-1)
  • docs/cli/message.md (modified, +1/-1)
  • extensions/telegram/src/send.test.ts (modified, +12/-1)
  • extensions/telegram/src/send.ts (modified, +6/-4)
  • src/agents/tools/message-tool.ts (modified, +3/-2)
  • src/cli/program/message/register.send.ts (modified, +1/-1)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.discord-group.json (modified, +2/-2)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.heartbeat-turn.json (modified, +2/-2)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.telegram-direct.json (modified, +2/-2)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/discord-group-codex-message-tool.md (modified, +6/-6)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-direct-codex-message-tool.md (modified, +6/-6)
  • test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-heartbeat-codex-tool.md (modified, +6/-6)

Code Example

TOKEN=$(jq -r '.channels.telegram.botToken' /path/to/openclaw.json)
curl -s -F chat_id=<chat> -F document=@/path/file.mp4 \
  "https://api.telegram.org/bot${TOKEN}/sendDocument"
# → {"ok": true, "result": {"message_id": ..., "video": {...}}}

---

openclaw message send --channel telegram --target <chatId> --media /path/to/file.mp4

---

[telegram] video failed: Network request for 'sendVideo' failed!
   HttpError: Network request for 'sendVideo' failed!
RAW_BUFFERClick to expand / collapse

Summary

openclaw message send --channel telegram --target <chat> --media <file.mp4> routes MP4 files through Telegram's sendVideo endpoint, which fails with Network request for 'sendVideo' failed! (no further detail). The documented --force-document flag, intended to "send media as document to avoid Telegram compression," does not override the routing — the same sendVideo call is made and the same error returned.

The result is that no video file can be delivered to Telegram via message send regardless of flags, and the agent CLI returns exit 0 with the failure only visible in stderr lines, so callers (scripts, agents) think the send succeeded.

Workaround

Bypass the plugin and POST directly to Telegram's bot API with sendDocument — works first try, in seconds, and Telegram still renders an inline video player for MP4s. So the underlying network and bot setup are fine; it's specifically the plugin's routing.

TOKEN=$(jq -r '.channels.telegram.botToken' /path/to/openclaw.json)
curl -s -F chat_id=<chat> -F document=@/path/file.mp4 \
  "https://api.telegram.org/bot${TOKEN}/sendDocument"
# → {"ok": true, "result": {"message_id": ..., "video": {...}}}

Steps to reproduce

  1. Have a working Telegram bot configured in openclaw.json (text sends fine).
  2. Have any valid .mp4 file on disk under 50 MB (the bot API hard limit).
  3. Run:
    openclaw message send --channel telegram --target <chatId> --media /path/to/file.mp4
  4. Wait ~30–60s. Stderr eventually shows:
    [telegram] video failed: Network request for 'sendVideo' failed!
    HttpError: Network request for 'sendVideo' failed!
  5. Exit code is 0 despite the failure.
  6. Re-run with --force-document added — same error, same routing through sendVideo.

Reproduced with a 7.8 MB H.264 MP4 (1224×720, 94s, valid container) — same file uploads cleanly via direct sendDocument.

Expected behavior

Either:

  • (A) --force-document actually routes through sendDocument, OR
  • (B) When sendVideo fails, the plugin auto-falls back to sendDocument (Telegram's recommended general-purpose endpoint), OR
  • (C) Both — --force-document as explicit override AND auto-fallback when typed endpoints fail

In any case, exit code should be non-zero on failure so callers can react.

Actual behavior

  • Routes through sendVideo regardless of --force-document
  • sendVideo fails (likely codec/container strictness on Telegram's side, or upload timeout — the error message gives no detail)
  • No fallback to sendDocument even though that's the universally-compatible path
  • Process exits 0, hiding the failure from callers

Environment

  • OpenClaw Version: 2026.4.29 (a448042)
  • OS: macOS Darwin 25.3.0 (Apple Silicon)
  • Integration: Telegram bot API
  • File tested: 7.8 MB MP4, H.264, 1224×720, 94s, well under the 50 MB bot-API limit

Why this matters

Video delivery is a common request (downloaded YouTube/X videos, screen recordings, generated content). The current state means any agent skill that downloads a video and tries to deliver it via message send --media silently fails, and the agent has no way to detect this without scraping stderr.

Related: #74061 (<final>MEDIA:... regression in 2026.4.26+) is a different code path with the same outward symptom ("Media failed"). Fixing this --media bug doesn't fix #74061 and vice versa.

Suggested fix priority

  1. Make --force-document actually force sendDocument (one-line routing change)
  2. Add sendDocument auto-fallback when typed endpoint fails (sendVideo / sendAudio / sendPhoto → retry as document)
  3. Fix exit code: any non-200 final outcome → exit non-zero

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…

FAQ

Expected behavior

Either:

  • (A) --force-document actually routes through sendDocument, OR
  • (B) When sendVideo fails, the plugin auto-falls back to sendDocument (Telegram's recommended general-purpose endpoint), OR
  • (C) Both — --force-document as explicit override AND auto-fallback when typed endpoints fail

In any case, exit code should be non-zero on failure so callers can react.

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 [Bug]: `message send --media` routes .mp4 through sendVideo and `--force-document` does not override [2 pull requests, 3 comments, 4 participants]