Discord forwarded message content now parsed
Discord forwarded messages now surface both text and attachments in the agent context, even when Discord delivers the content via referenced_message instead of message_snapshots.
Discord's forward feature was broken: when users forwarded messages between channels, the agent received only metadata like sender and timestamp, with the actual content missing. This forced users to copy-paste text instead of using Discord's native Forward.
The Discord integration now falls back to referencedMessage when message_snapshots are absent. Both text and attachments are extracted from the referenced message and included in the agent context, formatted with an authorship header so agents can see who originally sent the content.
This matters for multi-agent coordination built on Discord—forwarding is now a viable handoff mechanism between agents running in different channels. The fix is scoped strictly to Discord and only affects messages where messageReference.type === Forward, leaving ordinary replies untouched.
View Original GitHub Description
Summary
- Problem: Discord forwarded messages could reach the agent with only
Conversation infometadata when Discord populatedreferenced_messagebut did not includemessage_snapshots. - Why it matters: forwarded handoff content becomes invisible to the agent, which breaks Discord-based multi-agent coordination and forces users to copy-paste instead of using Forward.
- What changed: the Discord inbound message path now falls back to
messageReference.type === Forward+referencedMessagewhen snapshots are absent, for both forwarded text and forwarded attachments. - What did NOT change (scope boundary): this PR does not change ordinary reply handling, thread-starter resolution beyond existing behavior, or non-Discord channels.
Change Type (select all)
- Bug fix
- Feature
- Refactor required for the fix
- Docs
- Security hardening
- Chore/infra
Scope (select all touched areas)
- Gateway / orchestration
- Skills / tool execution
- Auth / tokens
- Memory / storage
- Integrations
- API / contracts
- UI / DX
- CI/CD / infra
Linked Issue/PR
- Closes #61664
- Related #60139
- This PR fixes a bug or regression
Root Cause / Regression History (if applicable)
- Root cause:
extensions/discord/src/monitor/message-utils.tsonly treatedmessage_snapshotsas forwarded-message content. When Discord delivered a forward viamessage_reference.type = Forwardplusreferenced_message, OpenClaw kept the reply metadata but dropped the forwarded body and attachments from the main inbound content path. - Missing detection / guardrail: there was no regression test for forwarded messages that carry content only in
referencedMessage. - Prior context (
git blame, prior PR, issue, or refactor if known): #60139 fixed a related Discord forwarded-message gap for thread starter resolution, but explicitly stayed out ofmessage-utils.tsand regular inbound processing. - Why this regressed now: this appears to be an unsupported Discord forward representation rather than a recent regression introduced by this PR.
- If unknown, what was ruled out: the issue is not limited to
message_snapshots; local code inspection confirmed the regular inbound path already handled snapshots but had noreferencedMessagefallback.
Regression Test Plan (if applicable)
- Coverage level that should have caught this:
- Unit test
- Seam / integration test
- End-to-end test
- Existing coverage already sufficient
- Target test or file:
extensions/discord/src/monitor/message-utils.test.ts - Scenario the test should lock in: forwarded Discord messages with
messageReference.type === Forwardand no snapshots still surface referenced text and referenced attachments to the agent, while ordinary replies do not get treated as forwarded context. - Why this is the smallest reliable guardrail: the bug is isolated to the Discord message text/media normalization helpers, so unit tests on that seam directly cover the dropped-content path without requiring a live Discord runtime.
- Existing test that already covers this (if any): existing tests already covered snapshot-based forwarded content only.
- If no new test is added, why not: N/A
User-visible / Behavior Changes
Discord forwarded messages now preserve forwarded body text and forwarded attachments in the inbound agent context even when Discord sends them via referenced_message instead of message_snapshots.
Diagram (if applicable)
Before:
[Discord forward] -> referenced_message only -> metadata reaches agent -> forwarded content missing
After:
[Discord forward] -> referenced_message only -> fallback extracts body/media -> agent sees forwarded content
Security Impact (required)
- New permissions/capabilities? (
Yes/No) No - Secrets/tokens handling changed? (
Yes/No) No - New/changed network calls? (
Yes/No) No - Command/tool execution surface changed? (
Yes/No) No - Data access scope changed? (
Yes/No) No - If any
Yes, explain risk + mitigation: N/A
Repro + Verification
Environment
- OS: Ubuntu 24.04.3
- Runtime/container: Node 22 / pnpm workspace
- Model/provider: N/A
- Integration/channel (if any): Discord
- Relevant config (redacted): N/A
Steps
- Create a Discord message object whose forward content is available only via
messageReference.type === ForwardandreferencedMessage, with nomessage_snapshots. - Run the Discord inbound message normalization helpers.
- Confirm the agent-facing text/media include the forwarded content, and that ordinary replies still do not get treated as forwarded context.
Expected
- Forwarded referenced text is included in the inbound content.
- Forwarded referenced attachments are preserved in forwarded media resolution.
- Non-forward replies remain unchanged.
Actual
- Matches expected with the patch.
Evidence
- Failing test/log before + passing after
- Trace/log snippets
- Screenshot/recording
- Perf numbers (if relevant)
Human Verification (required)
- Verified scenarios: ran
pnpm test -- extensions/discord/src/monitor/message-utils.test.ts; confirmed new tests pass for referenced forwarded text, referenced forwarded attachments, and ordinary reply non-regression. Ranpnpm buildsuccessfully in the main workspace before preparing the clean PR branch. - Edge cases checked: snapshot-based forwarded messages still work; ordinary replies with
messageReference.type === Defaultare not treated as forwarded context; forwarded attachments still resolve when snapshots are absent. - What you did not verify: end-to-end with a live Discord forwarded message event against a running OpenClaw instance.
Review Conversations
- I replied to or resolved every bot review conversation I addressed in this PR.
- I left unresolved only the conversations that still need reviewer or maintainer judgment.
Compatibility / Migration
- Backward compatible? (
Yes/No) Yes - Config/env changes? (
Yes/No) No - Migration needed? (
Yes/No) No - If yes, exact upgrade steps: N/A
Risks and Mitigations
- Risk: Discord could send message references for ordinary replies and forwarded messages through the same fields in some future shape change.
- Mitigation: the fallback is gated specifically on
messageReference.type === Forward, and there is a regression test asserting ordinary replies stay unchanged.
- Mitigation: the fallback is gated specifically on
- Risk: snapshot-based forwarded handling could regress while adding the fallback path.
- Mitigation: existing snapshot tests still pass, and the fallback only runs when snapshots are absent.
AI-Assisted
- AI-assisted (Codex)
- Fully tested locally for the touched surface
- Understand what the code does