Summary
handleAgentOutboundMessage (pkg/hub/handlers_agent_messaging.go) is
documented — both in its doc comment and in an inline comment above the
recipient-resolution block — as defaulting the recipient to the agent's
creator when none is explicitly specified:
"The recipient defaults to the agent's creator when not explicitly
specified."
// Resolve recipient: explicit takes precedence; implicit defaults to agent creator.
No such fallback is implemented. When both recipient and recipient_id
are empty, the handler goes straight to:
if recipientID == "" && recipient == "" {
ValidationError(w, "recipient is required — specify a user with 'user:<name>' or 'user:<email>'", nil)
return
}
Impact
This breaks every caller that relies on implicit recipient resolution — most
notably the assistant-reply Stop hook
(pkg/sciontool/hooks/handlers/hub.go) that auto-forwards an agent's final
reply via SendOutboundMessage(). That call only ever sets Msg, Type,
Visibility, and Metadata — never Recipient/RecipientID — so every
automatic forward of an agent's reply is rejected with a 400. This affects
both the web dashboard's "Messages" tab and any plugin built on top of
outbound messages (e.g. the Telegram plugin): the agent's reply is captured
successfully by the hook, then silently fails to deliver.
Repro
- Start an agent, send it an inbound message (e.g. via Telegram plugin or
scion message).
- Let it reply. The Stop hook fires
SendOutboundMessage() with no
recipient.
- Server logs a
400 validation_error: "recipient is required..."
immediately after the hook's message-capture step. The reply never
reaches any consumer (dashboard Messages tab, Telegram, etc).
Fix
PR incoming: implement the documented fallback by resolving
agent.CreatedBy (falling back to agent.OwnerID) via store.GetUser when
no recipient is supplied at all, before returning the validation error.
Summary
handleAgentOutboundMessage(pkg/hub/handlers_agent_messaging.go) isdocumented — both in its doc comment and in an inline comment above the
recipient-resolution block — as defaulting the recipient to the agent's
creator when none is explicitly specified:
No such fallback is implemented. When both
recipientandrecipient_idare empty, the handler goes straight to:
Impact
This breaks every caller that relies on implicit recipient resolution — most
notably the assistant-reply Stop hook
(
pkg/sciontool/hooks/handlers/hub.go) that auto-forwards an agent's finalreply via
SendOutboundMessage(). That call only ever setsMsg,Type,Visibility, andMetadata— neverRecipient/RecipientID— so everyautomatic forward of an agent's reply is rejected with a 400. This affects
both the web dashboard's "Messages" tab and any plugin built on top of
outbound messages (e.g. the Telegram plugin): the agent's reply is captured
successfully by the hook, then silently fails to deliver.
Repro
scion message).SendOutboundMessage()with norecipient.
400 validation_error: "recipient is required..."immediately after the hook's message-capture step. The reply never
reaches any consumer (dashboard Messages tab, Telegram, etc).
Fix
PR incoming: implement the documented fallback by resolving
agent.CreatedBy(falling back toagent.OwnerID) viastore.GetUserwhenno recipient is supplied at all, before returning the validation error.