Skip to content

[Bug]: Telegram outbound rejects trusted generated HTML after staging strips trusted-root marker (PR #87982 missed e2e case) #90557

Description

@wangwllu

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

After PR #87982 enabled trusted generated text/html for host-read outbound, Telegram delivery still drops the attachment because the staged copy under ~/.openclaw/media/outbound/<uuid>.html is no longer inside /tmp/openclaw/, so the second loadWebMedia call fails the isTrustedGeneratedHostReadHtmlPath root-check.

Steps to reproduce

  1. Run OpenClaw 2026.6.1 with a Telegram bot account configured.
  2. From an agent reply, emit an absolute MEDIA:/tmp/openclaw/<file>.html directive (file is a real generated HTML report, owned by the same uid as the gateway, mode 0644, nlink=1, valid UTF-8, doctype <!doctype html>).
  3. Observe gateway log: OutboundDeliveryError: hostReadCapability permits only validated plain-text documents and trusted generated HTML reports for local reads. No file is delivered.

I instrumented dist/web-media-B4RFpB_P.js (isTrustedGeneratedHostReadHtmlPath + the gate602 site) with console.error probes and confirmed the exact flow:

[HTMLDBG] isTrustedPath {
  filePath: "/tmp/openclaw/unread-fetch-report.html",
  resolvedFilePath: "/private/tmp/openclaw/unread-fetch-report.html",
  resolvedTmpRoot:  "/private/tmp/openclaw",
  inside: true
}
[HTMLDBG] gate602 { hostReadCapability: true, hostReadDeclaredMime: "text/html", trustedGeneratedHtmlPath: true }
[HTMLDBG] isTrustedHtml OK

# same outbound flow, second loadWebMedia call:
[HTMLDBG] isTrustedPath {
  filePath: "/Users/<user>/.openclaw/media/outbound/unread-fetch-report---<uuid>.html",
  resolvedFilePath: "/Users/<user>/.openclaw/media/outbound/unread-fetch-report---<uuid>.html",
  resolvedTmpRoot:  "/private/tmp/openclaw",
  inside: false
}
[HTMLDBG] gate602 { hostReadCapability: true, hostReadDeclaredMime: "text/html", trustedGeneratedHtmlPath: false }
→ throw OutboundDeliveryError: hostReadCapability permits only validated plain-text documents and trusted generated HTML reports

Expected behavior

Per PR #87982, a .html file whose realpath is inside /tmp/openclaw/ should be deliverable as a Telegram document. PDF works in the exact same surface (verified at 12:23 with a 1.34 MB PDF: operation=sendDocument deliveryKind=document). HTML should work analogously. The PR description even says "valid generated .html reports under the OpenClaw temp root load as text/html documents for host-read delivery" — which is true on the first call but the staging step then re-invokes loadWebMedia on the staged copy, which is not under the temp root.

Actual behavior

Telegram outbound is rejected with OutboundDeliveryError: hostReadCapability permits only validated plain-text documents and trusted generated HTML reports for local reads. No "Media failed" placeholder reaches the chat — the message is silently dropped. PDF/PNG attachments through the same code path succeed because they don't go through the text/html trusted-root branch at all.

Reproduced 4 times today across different filenames, permission modes (0600 / 0644), and gateway restarts; every attempt logs the same error at the same web-media.ts site.

OpenClaw version

2026.6.1 (commit 2e08f0f)

Operating system

macOS 26.4 (Darwin 25.4.0, arm64)

Install method

npm global

Model

claude-cli/Claude-Opus-4.7

Provider / routing chain

Direct Telegram Bot API (polling), bot @yoyo_li_bot

Additional provider/model setup details

Channel: telegram plugin built-in. No proxy on outbound (only inbound polling proxy).

Logs, screenshots, and evidence

Source: ~/Library/Logs/openclaw/gateway.log and /tmp/openclaw/openclaw-2026-06-05.log.

2026-06-05T13:06:35 [HTMLDBG] isTrustedPath inside=true   (original /tmp/openclaw/...html)
2026-06-05T13:06:35 [HTMLDBG] gate602 trustedGeneratedHtmlPath=true
2026-06-05T13:06:36 [HTMLDBG] isTrustedHtml OK
2026-06-05T13:06:37 [HTMLDBG] isTrustedPath inside=false  (staged ~/.openclaw/media/outbound/...html)
2026-06-05T13:06:37 [HTMLDBG] gate602 trustedGeneratedHtmlPath=false
2026-06-05T13:06:37 ERROR channels/telegram: OutboundDeliveryError: hostReadCapability permits only validated plain-text documents and trusted generated HTML reports for local reads

The contrast in the same trace is decisive: the first isTrustedPath evaluation passes; the second one (after staging) fails because resolvedFilePath no longer lives under resolvedTmpRoot=/private/tmp/openclaw.

Suspected fix region: either (a) resolveOutboundAttachmentFromUrl (or whichever staging step copies /tmp/openclaw/*.html to ~/.openclaw/media/outbound/) should preserve the trusted-root marker through the post-stage loadWebMedia, or (b) isTrustedGeneratedHostReadHtmlPath should also accept the ~/.openclaw/media/outbound/ staging root as trusted (with the same nlink/symlink guards).

PR #87982 explicitly notes: "What was not tested: live Telegram Bot API delivery". This issue is the missed e2e case.

Impact and severity

Affected channel: Telegram. Severity: blocks workflow (HTML attachments unsendable). Frequency: always. Workaround: render HTML to PDF via headless Chrome — PDF goes through HOST_READ_ALLOWED_DOCUMENT_MIMES and survives staging.

Additional information

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions