Skip to content

[Bug]: 2026.4.22 Slack MPIM/group: internal "Working…" tool-trace messages leak into group chats as user-visible messages #70912

@jrex-jooni

Description

@jrex-jooni

Summary

In 2026.4.22, the runtime-level "Working… / tool: … / tool args …" progress messages (normally hidden in group chats) are leaking into Slack group DMs (MPIMs) as real, user-visible messages. This exposes internal tool names and arguments (including fetched URLs and message/reaction targets) to group participants.

This happens even when no agent has verboseDefault set anywhere in config — implying the global fallback default for shouldEmitVerboseProgress() is effectively "on" for this surface, or the gate intended to suppress group delivery isn't firing.

Environment

  • Version: OpenClaw 2026.4.22 (upgraded from 2026.4.20, same day)
  • Channel: Slack
  • Chat type: Slack MPIM (multi-person IM / group DM)
  • Agent: default main agent, Anthropic claude-opus-4-7
  • Config: no verbose* keys present anywhere; agents.defaults.thinkingDefault: "medium", per-agent thinkingDefault: "high" for main (not relevant to this bug)

Repro

  1. Slack MPIM with bot + 2 human users.
  2. Human sends a URL into the MPIM (no mention of bot).
  3. Bot is configured to consider whether to react / respond; on this turn it decided to call web_fetch then message (react with emoji) and emit NO_REPLY.
  4. The two tool invocations resulted in two separate real Slack messages posted by the bot into the MPIM:
Working…
• web_fetch from https://www.reddit.com/r/AncientAliens/s/<redacted> (max 3000 chars)
• tool: web_fetch
• web_fetch from https://www.reddit.com/r/AncientAliens/s/<redacted> (max 3000 chars)
Working…
• message message 1776999987.800299, emoji alien
• tool: message
• message message 1776999987.800299, emoji alien

The bot's correct NO_REPLY was honored (no final reply), but the internal trace still shipped.

Expected

No "Working…" or tool-trace messages should be emitted to Slack group chats (MPIM or channel). These are runtime diagnostics, not user-facing content.

Code analysis

Trace generator: /app/dist/dispatch-BbwSt8e4.js:583-596 (maybeSendWorkingStatus):

const maybeSendWorkingStatus = async (label) => {
    if (suppressDelivery) return;
    const normalizedLabel = normalizeWorkingLabel(label);
    if (!shouldEmitVerboseProgress() || !shouldSendToolStartStatuses || ...) return;
    ...
    const payload = { text: `Working: ${normalizedLabel}` };
    ...
};

Two gates:

  1. shouldSendToolStartStatuses (line 482):

    const shouldSendToolStartStatuses = ctx.ChatType !== "group" || ctx.IsForum === true;

    Intent: suppress tool-start statuses in group chats unless it's a forum.

  2. shouldEmitVerboseProgress() (line 218-229):

    const currentLevel = normalizeVerboseLevel(entry?.verboseLevel ?? "");
    if (currentLevel) return currentLevel !== "off";
    return params.fallbackLevel !== "off";

    With no session-level verbose set and config verboseDefault unset, fallback resolves to "off" via nullish coalescing, so this gate should return false.

Hypothesis on why both gates failed here:

  • Gate 1 (ChatType): Slack's ingress has two paths that set ChatType for MPIMs differently:

    • /app/dist/extensions/slack/prepare-BH5U3jEx.js:149-151: isGroup = channelType === "mpim"; chatType = isDirectMessage ? "direct" : isGroup ? "group" : "channel"correct.
    • /app/dist/extensions/slack/prepare-BH5U3jEx.js:1261,1343: ChatType: isDirectMessage ? "direct" : "channel"wrong for MPIMs (forces channel, loses the group distinction).

    If the second path fired for this turn, shouldSendToolStartStatuses evaluates to true and the trace is allowed through.

  • Gate 2 (verbose): unclear how this returned true given no verboseDefault is set. Possibly a fallback resolution bug introduced in 2026.4.22, or a default changed somewhere. Haven't pinpointed.

The two-gate design is correct; the implementation has at least one broken gate (MPIM ChatType branch inconsistency), and possibly a second (verbose fallback).

Impact

  • Information leak: internal tool names, arguments, and target message IDs posted to group chats.
  • Trust: users in group chats see what looks like bot noise/spam.
  • Silent: affected operators may not notice until a participant complains.

Workaround

Set agents.defaults.verboseDefault: "off" explicitly in config. This forces gate 2 to always return false regardless of the fallback-resolution bug:

{
  "agents": {
    "defaults": {
      "verboseDefault": "off"
    }
  }
}

Not a proper fix — masks the root cause — but stops the leak immediately.

Suggested fix direction

  1. Audit /app/dist/extensions/slack/prepare-BH5U3jEx.js and normalize all MPIM paths to set ChatType: "group".
  2. Re-check shouldEmitVerboseProgress fallback when both sessionEntry.verboseLevel and agents.defaults.verboseDefault are unset — should default to "off", not "on".
  3. Consider adding a second hard gate in maybeSendWorkingStatus that refuses to emit to any non-direct-message surface regardless of verbose state, to make this class of leak impossible.

Related

  • #50690 — "Prevent fake-progress messages with a runtime pre-send policy layer" (related policy layer idea)
  • #67199, #54919, #52537, #55790, #66607, #59416, #69440, #67888, #64830 — other thinkingDefault / session-default cascade issues (not this bug, but same class of "defaults silently ignored")

Screenshot

User-provided Slack screenshot of the leak is available on request (redacted for MPIM participants' names).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions