#20186: fix(discord): thread mediaLocalRoots through reply delivery path
channel: discord
size: XS
Cluster:
Media Handling Improvements
## Summary
`deliverDiscordReply` sends media attachments via `sendMessageDiscord` but does not forward `mediaLocalRoots`. This causes local media files in agent workspace directories to be rejected by `assertLocalMediaAllowed`, since only the default state-dir roots are checked.
The outbound delivery path (`infra/outbound/deliver.ts`) already handles this correctly by calling `getAgentScopedMediaLocalRoots(cfg, agentId)`. This PR applies the same pattern to the Discord reply delivery path.
## Changes
- **`reply-delivery.ts`** — Add optional `mediaLocalRoots` param and forward it to all three `sendMessageDiscord` calls that carry a `mediaUrl`
- **`message-handler.process.ts`** — Supply `getAgentScopedMediaLocalRoots(cfg, route.agentId)` when calling `deliverDiscordReply`
- **`agent-components.ts`** — Same for the component interaction delivery path
- **`reply-delivery.test.ts`** — Add test asserting `mediaLocalRoots` is forwarded to `sendMessageDiscord`
4 files changed, +39 lines
## Reproduction
1. Configure an agent with a workspace directory outside the state dir
2. Have the agent generate or download a file to its workspace (e.g. an edited image)
3. Agent replies with the file as a media attachment via Discord
4. **Before fix:** `Local media path is not under an allowed directory` error
5. **After fix:** Media is sent successfully
## Testing
- [x] `pnpm build` — passes
- [x] `pnpm check` (format + types + lint) — passes
- [x] `pnpm test` — 1106 passed, 1 skipped, 0 failures
- [x] Tested end-to-end on a live Discord gateway with agent workspace media
## Note
`sendVoiceMessageDiscord` has a similar gap (its `VoiceMessageOpts` type does not accept `mediaLocalRoots`), but that's a separate concern requiring changes to the voice message API surface — left out of scope to keep this PR focused.
🤖 AI-assisted (Claude) — fully tested, all changes understood and reviewed
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a bug where Discord reply delivery (both from message handling and component interactions) failed to forward `mediaLocalRoots` to `sendMessageDiscord`, causing agent workspace media to be rejected by `assertLocalMediaAllowed`. The fix threads the `mediaLocalRoots` parameter through the reply delivery path, matching the pattern already used by the outbound delivery path in `src/infra/outbound/deliver.ts`.
- `deliverDiscordReply` gains an optional `mediaLocalRoots` parameter, forwarded to all three `sendMessageDiscord` call sites that include a `mediaUrl`
- Both callers (`processDiscordMessage` and `dispatchDiscordComponentEvent`) now supply `getAgentScopedMediaLocalRoots(cfg, agentId)`, consistent with the outbound adapter
- New test validates that `mediaLocalRoots` is correctly propagated for media payloads
- As noted in the PR, `sendVoiceMessageDiscord` has the same gap but is left out of scope
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge — it adds a well-scoped parameter plumbing fix consistent with existing patterns, with no behavioral regressions.
- The changes are minimal and mechanical: adding one optional parameter to a function signature and forwarding it at all appropriate call sites. The pattern directly mirrors the already-working outbound delivery path. All three `sendMessageDiscord` calls with `mediaUrl` now receive `mediaLocalRoots`. The parameter type (`readonly string[]`) matches the downstream `DiscordSendOpts` type exactly. A new test covers the change. Build, types, lint, and tests all pass per the PR.
- No files require special attention.
<sub>Last reviewed commit: 9469201</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#20488: fix(discord): pass mediaLocalRoots to sendMessageDiscord
by olyashok · 2026-02-19
89.2%
#20294: fix(message): thread mediaLocalRoots through channel plugin dispatch
by odrobnik · 2026-02-18
85.4%
#23627: fix(telegram,feishu): pass mediaLocalRoots through channel action a...
by rockkoca · 2026-02-22
83.9%
#19171: fix(feishu): pass mediaLocalRoots to sendMediaFeishu for agent-scop...
by whiskyboy · 2026-02-17
82.8%
#23148: fix: forward mediaLocalRoots in whatsapp plugin sendMedia
by MunemHashmi · 2026-02-22
81.2%
#14794: fix: parse inline MEDIA: tokens in agent replies
by explainanalyze · 2026-02-12
77.5%
#20913: fix: intercept Discord embed images to enforce mediaMaxMb
by MumuTW · 2026-02-19
77.4%
#22178: test(web): allow fixture roots in media local file tests
by Kansodata · 2026-02-20
77.2%
#19325: feat: support messages.mediaLocalRoots for custom media directories
by deggertsen · 2026-02-17
77.1%
#19399: telegram: fix MEDIA false positives and partial final drop
by HOYALIM · 2026-02-17
77.1%