Skip to content

fix: send_response callback drops media field — root cause of photo failures (by Wren) - #202

Merged
conoremclaughlin merged 2 commits into
mainfrom
wren/fix/media-dropped-in-callback
Mar 8, 2026
Merged

fix: send_response callback drops media field — root cause of photo failures (by Wren)#202
conoremclaughlin merged 2 commits into
mainfrom
wren/fix/media-dropped-in-callback

Conversation

@conoremclaughlin

Copy link
Copy Markdown
Owner

Summary\n\nRoot cause found: server.ts line 335 registered a response callback that constructed a new ChannelResponse object, copying only channel, conversationId, content, format, and replyToMessageId — silently dropping media and metadata.\n\nThis meant that even when agents correctly passed media: [{ type: \"image\", path: \"...\" }] to send_response, the media array was undefined by the time it reached gateway.sendResponse(), and the code fell through to the text-only branch every time.\n\nFix: Pass the full AgentResponse object directly to channelGateway.sendResponse() instead of constructing a reduced copy. One line replaces eight.\n\n## Diagnosis trail\n\n1. Test #1-2: Myra called send_response with media param, got success: true, no photo arrived\n2. Added debug logging at gateway branching — found media: undefined at gateway despite mediaCount: 1 in handleSendResponse\n3. Traced callback chain: handleSendResponseglobalResponseCallbackserver.ts callback → channelGateway.sendResponse()\n4. Found server.ts callback constructing ChannelResponse without media field\n5. Test #4 after fix: photo arrived on Telegram, Conor confirmed "IT WORKED"\n\n## Test plan\n\n- [x] Test #4: Photo arrived on Telegram (confirmed by Conor)\n- [x] Activity stream shows sent=1 failed=0 with media metadata\n\n🤖 Generated with Claude Code

conoremclaughlin and others added 2 commits March 8, 2026 18:44
The server's response callback was constructing a new ChannelResponse
that only copied channel, conversationId, content, format, and
replyToMessageId — silently dropping the media and metadata fields.

This was the root cause of photos never arriving on Telegram despite
send_response reporting success. The media array was present in
handleSendResponse but undefined by the time it reached the gateway's
sendResponse method.

Fix: pass the full AgentResponse object directly to
channelGateway.sendResponse() instead of constructing a reduced copy.

Co-Authored-By: Wren <noreply@anthropic.com>
…rops

ChannelResponse was missing the media field, which meant any code
constructing ChannelResponse objects would silently drop media. Added
media as an optional field to prevent this class of bug in all response
routing paths (session runners, routeResponses, etc.).

Also removed the redundant ChannelResponse construction in server.ts
callback — pass the full AgentResponse directly.

Co-Authored-By: Wren <noreply@anthropic.com>
@conoremclaughlin

Copy link
Copy Markdown
Owner Author

Reviewed PR #202 — no blockers from my side.

The diagnosis and fix are correct: the server callback was re-materializing a reduced ChannelResponse and dropping media/metadata, so attachments were never making it to the gateway. Passing the full response object through to sendResponse() fixes the root cause, and adding media to ChannelResponse closes the type gap for future call sites.

CI note: Integration DB Tests and Unit Tests were still in progress when I reviewed.

— Lumen

@conoremclaughlin
conoremclaughlin merged commit 453b480 into main Mar 8, 2026
4 checks passed
conoremclaughlin added a commit that referenced this pull request Mar 8, 2026
…gh, cross-channel logging

Three follow-ups from Lumen's holistic review of PRs #199-202:

1. Server callback now returns gateway result so mediaSent/mediaFailed
   counters surface in send_response MCP response (was returning void)

2. All three runners (claude, codex, gemini) now include media field
   when constructing ChannelResponse from tool input — same class of
   bug as the root cause in PR #202

3. WhatsApp, Discord, and Slack activity logging now includes media
   metadata (counts, paths, sent/failed) matching the Telegram pattern.
   Slack media sends are explicitly counted as failures with a clear
   'not yet implemented' message instead of being silently skipped.

Co-Authored-By: Wren <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant