DM: agent never posts a reply to a top-level DM — the turn context omits the send instruction when there is no thread root

Open Beginner friendly
#6,984 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
84/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
rust
Domain
backend

Research direction

Start in crates/buzz-acp/src/queue.rs and compare the Scope: dm branch with the channel branch, focusing on append_reply_instruction and append_new_thread_reply_instruction. Verify that a top-level DM context includes a send instruction anchored to the triggering event, and that the agent posts a reply without requiring a thread root.

Written by the indexing model from the issue text.

Description

Summary

When a user sends the first, top-level message in a DM to an agent, the agent runs the turn, does the
work, composes an answer — and never posts it. From the user's side the agent simply never replies.

The cause is in the prompt the harness builds: the DM branch attaches the "reply with buzz messages send"
instruction only when the triggering event is already inside a thread. A top-level DM has no thread root,
so the agent receives a context block that tells it how to read the conversation but never how to send
anything. The channel branch does not have this gap — it covers both the threaded and the top-level case.

Reproduction
  1. Open a DM with an agent.
  2. Send a message that is not a reply to anything (a fresh top-level message).
  3. The agent picks up the turn and works, but nothing is posted back.
  4. Now reply to your own message (or to any message in that DM) and ask again — the agent answers normally.
Evidence

Two consecutive turns in the same DM session. Only the second one contains the send instruction, and only the
second one results in a published event:

turn triggering message thread root context block buzz messages send calls reply posted
1 top-level DM absent 742 chars, no send instruction 0 no
2 reply (carries an e tag to turn 1) present 1466 chars, send instruction present 2 yes

Turn 1 was not a failed send. The agent completed the turn cleanly — it listed channels, read the day's
messages with buzz messages get, and produced a full answer as its final assistant text. It simply never
called the send command, and the relay log shows no kind:9 event published by the agent in that window.
The same agent posted replies normally in channels throughout the same period (4-15 send calls per turn).

For contrast, channel-scope turns in the same session period carry the instruction in both shapes:

Scope: channel
Channel: ...
Hint: Use `buzz messages get --channel <UUID>` for recent messages if needed.
IMPORTANT: This is a new top-level message. For ordinary replies in this turn, use
`--reply-to <event-id>` on `buzz messages send` ...

while the failing DM turn carried only:

Scope: dm
Channel: DM (#<uuid>)
<context hint>
Root cause

crates/buzz-acp/src/queue.rs, DM branch (Scope: dm):

// If this is a DM reply, include thread structural info as supplementary.
if let Some(ref root) = thread_tags.root_event_id {
    s.push_str(&format!("\nThread root: {root}"));
    ...
    if let Some(event_id) = reply_anchor {
        append_reply_instruction(&mut s, event_id);   // <- only reached inside a thread
    }
}

The channel branch immediately below handles the same two cases symmetrically:

// thread case
if let Some(event_id) = reply_anchor {
    append_reply_instruction(&mut s, event_id);
}
// top-level case
if let Some(event_id) = reply_anchor {
    append_new_thread_reply_instruction(&mut s, event_id);
}

append_reply_instruction and append_new_thread_reply_instruction are the only places that mention
buzz messages send in the turn context, so when neither fires the agent has no instruction to publish
anything.

Related: resolve_reply_anchor is documented as "Resolve the --reply-to anchor for a non-DM turn",
which suggests the DM path was intended to be handled separately and the top-level sub-case was missed.

Suggested fix

Give the DM branch the same top-level handling the channel branch has — attach
append_new_thread_reply_instruction (anchored to the triggering event) when thread_tags.root_event_id is
None. That keeps DM replies threaded on the triggering message, matching channel behaviour.

A cheaper alternative, if threading in DMs is deliberately looser, is to always state that replies are sent
with buzz messages send in the DM context block and leave the --reply-to anchor optional.

Impact

The first message a user ever sends an agent in a DM is by definition top-level, so this is the most likely
DM interaction to hit. The agent looks unresponsive with no error anywhere: no failed command, no rejected
event, nothing in the relay log — the work is done and the answer is discarded. Users have no way to tell
this apart from the agent being broken.

Dominant language
Rust
Stars
33.7k
Forks
4.4k
Avg merge
1d 21h
Merged PRs (30d)
239

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from block/buzz

All issues in block/buzz

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.