openclaw - ✅(Solved) Fix Telegram subagent completion fallback can queue raw child/internal output after mediated announce failure [1 pull requests, 1 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#78531Fetched 2026-05-07 03:35:50
View on GitHub
Comments
1
Participants
2
Timeline
9
Reactions
2
Author
Timeline (top)
mentioned ×3subscribed ×3closed ×1commented ×1

On OpenClaw 2026.5.5 (b1abf9d as reported by openclaw status), a sub-agent completion/announce failure path can queue or attempt to deliver raw child output to Telegram instead of a mediated, user-safe summary.

This appears distinct from the already-fixed updater/runtime-context leak: the remaining path is in sub-agent completion fallback / delivery recovery after the parent-agent mediated completion failed.

Related existing issues: #39032 and #25592.

Error Message

  • Raw error hash: sha256:115e5180d97d
  • Raw error fingerprint: sha256:21e6e417518f

Root Cause

I am deliberately not pasting the raw payload here because it is exactly the material that should not be exposed to Telegram or GitHub.

Fix Action

Fix / Workaround

Local mitigation I applied

This was a local hotfix in the installed dist only, not an upstream PR.

Patched:

PR fix notes

PR #78700: fix(agents): clean subagent fallback scaffolding

Description (problem / solution / changelog)

Summary

  • replace generated <<<BEGIN_UNTRUSTED_CHILD_RESULT>>> prompt sentinels with neutral <prompt-data> child-result blocks for parent-agent announce prompts
  • preserve child completion fallback output while unwrapping legacy marker lines and prompt-data wrappers before direct channel fallback
  • strip runtime-context/prompt-data scaffolding before write-ahead outbound queue persistence and rebuild queued batch plans from cleaned payloads

Fixes #78531.

Verification

  • pnpm test src/agents/sanitize-for-prompt.test.ts src/agents/subagent-announce-delivery.test.ts src/infra/outbound/sanitize-text.test.ts src/infra/outbound/deliver.test.ts src/agents/subagent-announce.format.e2e.test.ts src/agents/pi-embedded-helpers.sanitizeuserfacingtext.test.ts -- --reporter=verbose
  • pnpm test src/infra/outbound/sanitize-text.test.ts -- --reporter=verbose
  • pnpm exec oxfmt --check --threads=1 src/infra/outbound/sanitize-text.ts
  • git diff --check
  • Crabbox/Testbox pnpm check:changed on tbx_01kr030n90v5dny113kefyf666 (exitCode=0)

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/internal-events.ts (modified, +12/-8)
  • src/agents/sanitize-for-prompt.test.ts (modified, +24/-8)
  • src/agents/sanitize-for-prompt.ts (modified, +14/-4)
  • src/agents/subagent-announce-delivery.test.ts (modified, +45/-0)
  • src/agents/subagent-announce-delivery.ts (modified, +2/-1)
  • src/agents/subagent-announce-output.ts (modified, +11/-12)
  • src/agents/subagent-announce.format.e2e.test.ts (modified, +10/-6)
  • src/infra/outbound/deliver.test.ts (modified, +56/-0)
  • src/infra/outbound/deliver.ts (modified, +7/-2)
  • src/infra/outbound/sanitize-text.test.ts (modified, +94/-0)
  • src/infra/outbound/sanitize-text.ts (modified, +71/-1)
RAW_BUFFERClick to expand / collapse

Summary

On OpenClaw 2026.5.5 (b1abf9d as reported by openclaw status), a sub-agent completion/announce failure path can queue or attempt to deliver raw child output to Telegram instead of a mediated, user-safe summary.

This appears distinct from the already-fixed updater/runtime-context leak: the remaining path is in sub-agent completion fallback / delivery recovery after the parent-agent mediated completion failed.

Related existing issues: #39032 and #25592.

Environment

  • OpenClaw: 2026.5.5 (b1abf9d)
  • Installed package: [email protected]
  • npm latest at time checked: 2026.5.5
  • OS/runtime: macOS 26.4.1 arm64, Node 25.6.1
  • Gateway: LaunchAgent, /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 18789
  • Channel: Telegram direct message

Evidence observed locally (redacted)

A failed queued delivery existed at:

/Users/ethansk/.openclaw/delivery-queue/37bd4b88-388d-4270-8c5a-415f3e2e1b87.json

Metadata from that queued item:

  • id: 37bd4b88-388d-4270-8c5a-415f3e2e1b87
  • channel: telegram
  • to: telegram:6164541473
  • accountId: default
  • session key: agent:main:telegram:default:direct:6164541473
  • queued payload text length: 15962
  • retryCount: 3
  • lastError: Message must be non-empty for Telegram sends
  • enqueuedAt: 2026-05-06T11:56:26.534Z
  • lastAttemptAt: 2026-05-06T15:01:51.471Z

The queued payload contained raw/internal indicators including:

  • sawTargetNormalizationGain
  • target-normalization-gain-not-applied
  • missing-in-memory-cache
  • BEGIN_UNTRUSTED_CHILD_RESULT
  • BEGIN_OPENCLAW_INTERNAL_CONTEXT

I am deliberately not pasting the raw payload here because it is exactly the material that should not be exposed to Telegram or GitHub.

Relevant log/run identifiers:

  • Log: /tmp/openclaw/openclaw-2026-05-06.log
  • Run/event id: announce:v1:agent:main:subagent:f5f3eaaf-58a2-4322-aa1b-06e588aed2a7:d1e6ffed-0974-41c8-839f-57b714fb7e88
  • Provider failure seen near this path: service_unavailable_error / server_is_overloaded
  • Raw error hash: sha256:115e5180d97d
  • Raw error fingerprint: sha256:21e6e417518f

Likely failure path

From inspecting the installed dist files, the dangerous path appears to be:

  1. A sub-agent completes and subagent-announce-delivery tries to wake or mediate the requester session.
  2. The mediated parent-agent completion fails or is incomplete, e.g. due to provider overload.
  3. The completion fallback path uses task completion event content directly.
  4. The outbound delivery queue persists payloads before final Telegram/channel sanitization, so raw child/internal content can remain in the retry queue.
  5. Delivery recovery later retries that queued item. In this case it failed with Message must be non-empty for Telegram sends, likely because a later sanitizer/renderer stripped enough content to empty it, but the unsafe payload was still persisted and retried.

Files inspected locally:

  • /opt/homebrew/lib/node_modules/openclaw/dist/subagent-announce-delivery-De-sCDmZ.js
  • /opt/homebrew/lib/node_modules/openclaw/dist/delivery-queue-CX8x6Ho_.js
  • /opt/homebrew/lib/node_modules/openclaw/dist/send-C3qlmCZc.js
  • /opt/homebrew/lib/node_modules/openclaw/dist/sanitize-text-IbfTPlxP.js

Local mitigation I applied

This was a local hotfix in the installed dist only, not an upstream PR.

1. Stop direct fallback from using raw child event.result

Patched:

/opt/homebrew/lib/node_modules/openclaw/dist/subagent-announce-delivery-De-sCDmZ.js

Changed extractTaskCompletionFallbackText(event) so it no longer returns event.result. It now emits only task/status metadata plus a safe notice:

The child result was withheld from direct delivery so it can be summarized safely in-session.

Verification after patch:

  • safe notice present: yes
  • event.result referenced inside extractTaskCompletionFallbackText: no
  • backup created: subagent-announce-delivery-De-sCDmZ.js.bak-unsafe-child-fallback

2. Add outbound delimiter stripping for internal context / untrusted child result blocks

Patched:

/opt/homebrew/lib/node_modules/openclaw/dist/sanitize-text-IbfTPlxP.js

Added stripping for delimited blocks:

  • <<<BEGIN_OPENCLAW_INTERNAL_CONTEXT>>> ... <<<END_OPENCLAW_INTERNAL_CONTEXT>>>
  • <<<BEGIN_UNTRUSTED_CHILD_RESULT>>> ... <<<END_UNTRUSTED_CHILD_RESULT>>>

Verification after patch:

  • BEGIN_OPENCLAW_INTERNAL_CONTEXT guard present: yes
  • BEGIN_UNTRUSTED_CHILD_RESULT guard present: yes
  • backup created: sanitize-text-IbfTPlxP.js.bak-runtime-delimiters

3. Quarantine the unsafe queued item

Moved the unsafe pending queue entry out of active retry path:

/Users/ethansk/.openclaw/delivery-queue/failed/37bd4b88-388d-4270-8c5a-415f3e2e1b87.quarantined-unsafe-child-result-20260506T151901Z.json

Verification after quarantine:

  • pending /Users/ethansk/.openclaw/delivery-queue/*.json: empty
  • matching quarantined file exists under delivery-queue/failed/

Expected upstream fix

OpenClaw should make this impossible in more than one layer:

  1. Sub-agent completion fallback must never use raw child event.result for external channel delivery.
  2. Outbound queue entries should store already-sanitized external-delivery payloads, or reject/quarantine entries that contain internal runtime context / untrusted child result delimiters.
  3. Delivery recovery should fail closed for unsafe payloads instead of retrying them to Telegram/other channels.
  4. Tests should cover provider-failure/incomplete-mediated-completion paths, not just successful mediated summaries.
  5. Telegram/direct channel rendering should never receive BEGIN_OPENCLAW_INTERNAL_CONTEXT or BEGIN_UNTRUSTED_CHILD_RESULT blocks as sendable text.

Open question

The local queue item may or may not have been fully delivered before being sanitized/retried; logs confirmed retry failures for this queue id, but the original Telegram-visible message report came from a user-observed message (8995). Either way, raw/internal content reached a send/retry path and should be treated as a privacy/safety bug.

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 Telegram subagent completion fallback can queue raw child/internal output after mediated announce failure [1 pull requests, 1 comments, 2 participants]