#21466: Copilot/fix forwarded message visibility
channel: discord
size: XS
Cluster:
Signal and Discord Fixes
## Summary
Describe the problem and fix in 2–5 bullets:
- **Problem:** Forwarded Discord message content never reached the agent; `BodyForAgent` used `baseText` (excludes forwarded content) instead of `messageText` (includes forwarded content).
- **Why it matters:** Agent responses to forwarded messages were meaningless — the agent had no visibility into what was actually forwarded.
- **What changed:** Three field assignments in `finalizeInboundContext` in `src/discord/monitor/message-handler.process.ts`:
```typescript
// Before
BodyForAgent: baseText ?? text,
RawBody: baseText,
CommandBody: baseText,
// After
BodyForAgent: text,
RawBody: text,
CommandBody: text,
```
`text` is already assigned `messageText` (from `resolveDiscordMessageText(message, { includeForwarded: true })`).
- **What did NOT change:** `Body` (the combined/display body), forwarded media resolution, command authorization, routing, or any other path.
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [x] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
- Closes https://github.com/openclaw/openclaw/issues/21439
## User-visible / Behavior Changes
Agents now receive the full forwarded message text when a Discord user forwards a message. Previously the agent saw an empty or user-typed-only message; now it sees the `[Forwarded message from @User]\n<content>` block that `resolveDiscordForwardedMessagesText` already constructed correctly.
## Security Impact (required)
- New permissions/capabilities? No
- Secrets/tokens handling changed? No
- New/changed network calls? No
- Command/tool execution surface changed? No
- Data access scope changed? No
## Repro + Verification
### Environment
- OS: Any
- Runtime/container: Node 22+
- Model/provider: Any
- Integration/channel: Discord
- Relevant config (redacted): Discord bot with message forwarding enabled
### Steps
1. Forward any Discord message to an OpenClaw-connected Discord channel or DM.
2. Observe the agent's reply.
### Expected
- Agent response reflects the forwarded message content.
### Actual (before fix)
- Agent response ignores the forwarded content (sees empty/typed-only body).
## Evidence
- [ ] Failing test/log before + passing after
- [ ] Trace/log snippets
- [x] Screenshot/recording
- [ ] Perf numbers (if relevant)
## Human Verification (required)
- Verified scenarios: Tested forwarding:
<img width="554" height="392" alt="image" src="https://github.com/user-attachments/assets/33b97529-fbe6-456d-a0fe-81236a159d45" />
- Edge cases checked: None
- What you did **not** verify: Re-building openclaw with the code change. I manually modified the `dist` folder of my openclaw installation
## Compatibility / Migration
- Backward compatible? Yes
- Config/env changes? No
- Migration needed? No
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly: Revert the three-line change in `src/discord/monitor/message-handler.process.ts`.
- Files/config to restore: `src/discord/monitor/message-handler.process.ts`
- Known bad symptoms: Agent suddenly sees forwarded text it shouldn't — unlikely given `resolveDiscordMessageText` already had the correct output.
## Risks and Mitigations
- Risk: Commands embedded in forwarded messages might now be interpreted as user commands via `CommandBody`.
- Mitigation: Command authorization (`commandAuthorized`) is evaluated independently of this field; `CommandBody` is only the text surface, and existing auth gates remain unchanged.
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
> ## Bug
>
> When a user forwards a Discord message, the openclaw agent cannot see the forwarded message content. The agent sees an empty or near-empty message even though the forwarded text is correctly parsed.
>
> ## Root Cause
>
> In `src/discord/monitor/message-handler.process.ts`, the `BodyForAgent`, `RawBody`, and `CommandBody` fields in the `finalizeInboundContext` call (around line 518-523) use `baseText` instead of the full `messageText`/`text` that includes forwarded content.
>
> The preflight phase correctly resolves two text values:
> - `baseText` = `resolveDiscordMessageText(message, { includeForwarded: false })` — only the user's own typed content
> - `messageText` = `resolveDiscordMessageText(message, { includeForwarded: true })` — includes forwarded message text
>
> However, `BodyForAgent`, `RawBody`, and `CommandBody` are all set to `baseText`, which **excludes** forwarded content. Since `BodyForAgent` is what the LLM/agent actually receives as the user's message, the agent never sees the forwarded message.
>
> ## Fix
>
> In `src/discord/monitor/message-handler.process.ts`, change lines 520-522 from:
>
> ```typescript
> const ctxPayload = finalizeInboundContext({
> Body: combinedBody,
> BodyForAgent: baseText ?? text,
> InboundHistory: inboundHistory,
> RawBody: baseText,
> CommandBody: baseText,
> ```
>
> to:
>
> ```typescript
> const ctxPayload = finalizeInboundContext({
> Body: combinedBody,
> BodyForAgent: text,
> InboundHistory: inboundHistory,
> RawBody: text,
> CommandBody: text,
> ```
>
> Where `text` is already assigned `messageText` (which includes forwarded content) on line 321:
> ```typescript
> const text = messageText;
> ```
>
> This ensures the agent sees the full message including the `[Forwarded message from @User]\n<forwarded content>` that `resolveDiscordForwardedMessagesText` already correctly constructs.
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
*This pull request was created from Copilot chat.*
>
<!-- START COPILOT CODING AGENT TIPS -->
---
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. [Learn more about Advanced Security.](https://gh.io/cca-advanced-security)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Changed `BodyForAgent`, `RawBody`, and `CommandBody` to use `text` (which includes forwarded message content) instead of `baseText` (which excludes forwarded content). This ensures agents can see the full forwarded message text that Discord users forward, fixing a bug where agents responded to forwarded messages without seeing the forwarded content.
The change is surgical and correct:
- `text` is assigned from `messageText` on line 321, which calls `resolveDiscordMessageText(message, { includeForwarded: true })`
- `baseText` excludes forwarded content by calling `resolveDiscordMessageText(message, { includeForwarded: false })`
- Command authorization is computed in preflight using `baseText` (line 491 in message-handler.preflight.ts), so forwarded commands won't bypass security gates
- The change only affects what the agent sees, not the display body or authorization logic
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge - it's a targeted 3-line fix that correctly addresses forwarded message visibility without introducing security risks
- The change is minimal, well-understood, and correctly fixes the forwarded message bug. Command authorization happens in preflight using `baseText` (which excludes forwarded content), so security gates remain intact. The fix only changes what text the agent receives, which is exactly what's needed. The PR includes manual verification with a screenshot.
- No files require special attention
<sub>Last reviewed commit: 53fe8e7</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#17254: fix(discord): intercept text-based slash commands instead of forwar...
by robbyczgw-cla · 2026-02-15
77.2%
#20186: fix(discord): thread mediaLocalRoots through reply delivery path
by pvoo · 2026-02-18
75.6%
#20488: fix(discord): pass mediaLocalRoots to sendMessageDiscord
by olyashok · 2026-02-19
75.5%
#16194: fix: route exec approvals to explicit targets regardless of session...
by MisterGuy420 · 2026-02-14
74.6%
#19632: fix: suppressToolErrors now suppresses exec tool failure notifications
by Gitjay11 · 2026-02-18
74.5%
#8368: fix(telegram): preserve forwarded message metadata during debounce ...
by PatrickBauer · 2026-02-03
74.2%
#20009: fix(discord): immediately defer interactions to prevent timeouts
by Gitjay11 · 2026-02-18
74.2%
#17648: fix: Discord guild channel detection using rawMessage.guild_id
by MisterGuy420 · 2026-02-16
73.9%
#16685: Fix cli agents/approvals/discord routing edge cases
by craftowen · 2026-02-15
73.9%
#20294: fix(message): thread mediaLocalRoots through channel plugin dispatch
by odrobnik · 2026-02-18
73.8%