fix(cli): reject empty message content in messages send - #5809
fix(cli): reject empty message content in messages send#5809RockyMountainInfoTech wants to merge 1 commit into
Conversation
An agent running `buzz messages send --content -` with a broken or missing stdin producer reads 0 bytes, and every layer reports success: the relay accepts the event, --mention still notifies, and the caller gets a real event_id back — while the recipient sees a blank message. Observed repeatedly in agent fleets (10 confirmed producerless sends over two weeks in one deployment). Guard at the send call site, not in read_or_stdin: that helper has other call sites where empty passthrough is intentional. Attachment-only messages (files with no caption) remain legitimate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Andrew Ivie <andrew1ivie@gmail.com>
|
two other open PRs are on this exact ground: #5505 (reject blank message bodies at every write layer) and #5394 (reject empty stream messages at CLI, SDK and relay ingest). worth resolving to one before review — three branches editing the same send path will conflict. on the diff itself: |
Chessing234
left a comment
There was a problem hiding this comment.
the same failure mode is still open one function down — cmd_send_diff_message reads read_or_stdin(&p.diff) at messages.rs:728 with no empty guard, so messages send-diff --diff - against a dead producer publishes an empty diff block and reports success exactly the way you describe. the fleet-log rationale covers that call just as well.
rest checks out: files is the only attachment field on SendMessageParams so the gate isn't over-broad, and CliError::Usage really is exit 1 / user_error (error.rs:92,114).
Problem
An agent running
buzz messages send --content -with a broken or missing stdin producer reads 0 bytes and gets full success at every layer: the relay accepts the event,--mentionstill notifies recipients, and the caller receives a realevent_id. The recipient sees a blank message. Nothing anywhere reports a failure.This isn't hypothetical — auditing one agent fleet's session logs found 10 confirmed producerless
--content -sends over two weeks (the model composes prose in a variable, passes only the command string to its exec tool, and never pipes the content in). A second fleet independently hit the same class. Blank notifications read as agent malfunctions and cost real debugging time.Fix
Add
validate_message_contentinvalidate.rsand call it incmd_send_messageimmediately afterread_or_stdin:user_error) and a message that points at the likely cause (--content -with a producer that sent nothing).--filewith no caption) remain legitimate — the guard is gated onfiles.is_empty().read_or_stdin: that helper has ~11 call sites where empty passthrough is intentional (see theread_or_stdin_passthrough_empty_stringtest).Verification
cargo test -p buzz-cli: 347 passed, 0 failed (4 new unit tests: nonempty ok, empty rejected, whitespace-only rejected, empty-with-files ok)cargo clippy -p buzz-cli --all-targets: cleancargo fmt -p buzz-cli --check: clean🤖 Generated with Claude Code