Skip to content

onRouteFailure marker always lands in the primary agent's window #188

Open

Description

@Anarchid

The [discord-send-failed] marker for a failed speech route always lands in the primary agent's window, even when another agent authored the reply.

  • ChannelRegistry passes conversationId (the speaking agent) to the callback:
    this.onRouteFailure?.({ conversationId, channelId, reason, textLen: text.length });
  • The framework handler destructures only { channelId, reason, textLen } and calls this.addMessage(...) with no forAgent:

    agent-framework/src/framework.ts

    Lines 11864 to 11889 in 59a2a02

    onRouteFailure: ({ channelId, reason, textLen }) => {
    try {
    // Render a human-readable channel name when we can — a bare
    // snowflake in the marker is unresolvable for the agent (the
    // 2026-07-21 incident read as "a stale artifact", not a live
    // failure). The marker is `system: true`, so it is never
    // conversational and never influences routing.
    const label = channelId
    ? this.channelRegistry?.getDescriptor(channelId)?.label
    : undefined;
    const where = channelId
    ? label && label !== channelId
    ? `${label.startsWith('#') ? label : `#${label}`} (${channelId})`
    : channelId
    : 'the channel';
    this.addMessage(
    'user',
    [{
    type: 'text',
    text: `[discord-send-failed] Your previous reply (${textLen} chars) could not be delivered to ${where} (${reason}). It was saved to your archive but the human did not receive it.`,
    }],
    { system: true, kind: 'discord-send-failed', channelId: channelId ?? '', reason },
    );
    } catch (err) {
    console.error('onRouteFailure: failed to record send-failure marker:', err);
    }
  • An untargeted addMessage resolves to the primary agent:

    agent-framework/src/framework.ts

    Lines 11180 to 11184 in 59a2a02

    const agent = opts?.forAgent
    ? this.agents.get(opts.forAgent)
    : this.primaryAgentName
    ? this.agents.get(this.primaryAgentName)
    : this.agents.values().next().value;

Effect: in a multi-agent setup, a non-primary agent whose reply failed to route never sees the "your previous reply" notice, while the primary agent gets a notice about a reply it never wrote.

Suggested direction: take conversationId in the handler and pass { forAgent: conversationId } when it names a registered agent, falling back to the primary otherwise.

This bug is already on main. Greptile raised it on #163 because that PR adds another failure reason (missing receipt) that goes through the same handler.

Activity

  1. added a commit that references this issue on Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions