Skip to content

[Bug]: Observability tool_call telemetry leaks onto chat WebSocket, rendering permanent "unknown" tool cards #7151

@NiuBlibing

Description

@NiuBlibing

Affected component

runtime/daemon

Severity

S2 - degraded behavior

Current behavior

The chat UI intermittently renders standalone tool cards labeled "unknown" with a spinner that never resolves.

Root cause: the gateway uses one shared broadcast::Sender<serde_json::Value> (event_tx, crates/zeroclaw-gateway/src/lib.rs:906) as a firehose. Both the monitoring SSE endpoint /api/events (sse.rs:72) and the chat WebSocket (ws.rs:513) subscribe to it; publishers include the observability BroadcastObserver (lib.rs:1333) and the log hook (lib.rs:1343).

BroadcastObserver emits a telemetry frame that reuses the chat protocol's tool_call type string but with a different shape (sse.rs:162-173):

{"duration_ms":10611,"success":true,"timestamp":"2026-06-03T09:00:54.513459643+00:00","tool":"file_write","type":"tool_call"}

The chat WS forwards the broadcast firehose nearly unfiltered (ws.rs:635-639), so this reaches the chat frontend. The frontend tool_call handler keys on name — absent here (the field is tool) → falls back to "unknown" — and there is no output, so the card never resolves. The chat's real tool frames ({"type":"tool_call","id","name","args"}, ws.rs:1010) flow out-of-band over a per-turn channel, so the collision is purely incidental coupling via the shared bus.

Expected behavior

The chat WebSocket should not carry unexpected (observability/telemetry) events; or the frontend should handle such events gracefully without rendering meaningless cards. In other words: either isolate the channel/namespace at the source so monitoring events never flow onto the chat socket, or have the frontend gracefully ignore tool_call frames that do not match the chat tool-frame shape (missing name/output) instead of producing a never-resolving "unknown" card.

Steps to reproduce

# 1. Run the gateway and open the web chat against an agent.
# 2. Send a message that triggers a tool the agent executes (e.g. file_write).
# 3. The agent's tool execution emits an observability ToolCall event onto event_tx.
# 4. Observe a standalone "unknown" tool card (wrench icon, spinner) appear in
#    the chat that never resolves — separate from the real tool card.

Impact

Affected users: anyone using the web chat UI while tools execute.
Frequency: intermittent — whenever an observability tool_call event is broadcast during a chat session.
Consequence: confusing, never-resolving "unknown" cards clutter the transcript; cosmetic but erodes trust in the tool-activity view.

Logs / stack traces

Offending broadcast frame received by the chat WS client:

{"duration_ms":10611,"success":true,"timestamp":"2026-06-03T09:00:54.513459643+00:00","tool":"file_write","type":"tool_call"}

ZeroClaw version

commit 40be773

Rust version

rustc 1.95.0 (59807616e 2026-04-14)

Operating system

Linux 7.0.10-1-MANJARO x86_64 (Manjaro)

Regression?

Unknown

Pre-flight checks

  • I reproduced this on the latest master branch or latest release.
  • I redacted secrets, tokens, and personal data from all submitted content.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions