-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
[Bug]: Telegram outbound rejects trusted generated HTML after staging strips trusted-root marker (PR #87982 missed e2e case) #90557
Copy link
Copy link
Closed
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper 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 does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper 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 does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Priority
None yet
Bug type
Regression (worked before, now fails)
Beta release blocker
No
Summary
After PR #87982 enabled trusted generated
text/htmlfor host-read outbound, Telegram delivery still drops the attachment because the staged copy under~/.openclaw/media/outbound/<uuid>.htmlis no longer inside/tmp/openclaw/, so the secondloadWebMediacall fails theisTrustedGeneratedHostReadHtmlPathroot-check.Steps to reproduce
MEDIA:/tmp/openclaw/<file>.htmldirective (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>).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+ thegate602site) withconsole.errorprobes and confirmed the exact flow:Expected behavior
Per PR #87982, a
.htmlfile 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.htmlreports under the OpenClaw temp root load astext/htmldocuments for host-read delivery" — which is true on the first call but the staging step then re-invokesloadWebMediaon 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 thetext/htmltrusted-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.tssite.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:
telegramplugin built-in. No proxy on outbound (only inbound polling proxy).Logs, screenshots, and evidence
Source:
~/Library/Logs/openclaw/gateway.logand/tmp/openclaw/openclaw-2026-06-05.log.The contrast in the same trace is decisive: the first
isTrustedPathevaluation passes; the second one (after staging) fails becauseresolvedFilePathno longer lives underresolvedTmpRoot=/private/tmp/openclaw.Suspected fix region: either (a)
resolveOutboundAttachmentFromUrl(or whichever staging step copies/tmp/openclaw/*.htmlto~/.openclaw/media/outbound/) should preserve the trusted-root marker through the post-stageloadWebMedia, or (b)isTrustedGeneratedHostReadHtmlPathshould 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_MIMESand survives staging.Additional information
realpath(filePath)andrealpath(resolvePreferredOpenClawTmpDir())resolve identically through/private/tmpsymlink, so the symlink follow itself isn't the bug — the staging-copy origin is.operation=sendDocument, message Discord slash commands in threads fail with "This channel is not allowed." when using per-channel allowlist #1122 verified). PNG also works (different code path —image/pngdoesn't enterHOST_READ_DECLARED_TEXT_MIMES).