Skip to content

Empty-response retry loop on claude-opus-4-7 in Slack group threads (non-@mention discussion messages) #13248

@WaseemTheDream

Description

@WaseemTheDream

Summary

On claude-opus-4-7 (Anthropic provider) in Slack group threads, a genuine discussion message that is not an @mention of the bot can cause the model to reason into "don't reply" and emit no visible text. The gateway interprets that empty content as a generation failure and retries, producing the sequence:

  • Thinking-only response — nudging to continue (prefill-nudge retries)
  • Empty response from model — retrying
  • Final: Model produced reasoning but no visible response after all retries

The turn terminates with (empty) and the model cannot self-detect the loop, since the retry/nudge messages are system-injected and never surface in the model's own transcript on later turns.

Environment

  • Model: claude-opus-4-7 (provider: anthropic)
  • Surface: Slack group thread (not DM)
  • SOUL / system-prompt rules loaded: "speak less in groups", "silence means silence", "no pointless ack messages"
  • Relevant code: run_agent.py ~L10875–L11012 (thinking-only prefill + empty-response retry branches)

Reproduction

  1. Join a Slack group/channel that the bot is opted into via thread-session or free-response.
  2. Post a genuinely interesting discussion question addressed to the room, without @bot.
  3. Observe: either silence (intended) OR a 5-step empty-retry loop that still terminates with (empty).

Root Cause (hypothesis)

Two independently-correct behaviors compose badly:

  1. Prompt layer teaches the model that silence is a valid response in group chats when not @mentioned.
  2. Gateway layer (run_agent.py) treats "structured reasoning with no visible text" as a generation failure and retries up to 2× prefill-nudge + 3× empty-response retry + fallback provider switch.

When the model's chosen action is silence, the retry loop fights the intent instead of honoring it.

Context (run_agent.py)

# ~L10887
if _has_structured and self._thinking_prefill_retries < 2:
    # nudge: "(Please continue — that last turn had no visible response.)"

# ~L10934
if _truly_empty and (not _has_structured or _prefill_exhausted) and self._empty_content_retries < 3:
    # retry

Neither branch has a signal for "was the model actually addressed in this turn?"

Proposed Fixes

1. Gateway: plumb an is_addressed signal into the agent loop. Slack adapter already computes is_mentioned, reply_to_bot_thread, in_mentioned_thread, has_session. Pass a derived is_addressed boolean (true when this specific message mentions the bot, replies directly to it, or is in a DM) into AIAgent.run_conversation(). When is_addressed=False and the model returns thinking-only or empty on the first call, treat as intentional silence: skip the retry loop and return an empty final response that the adapter elides (no (empty) placeholder posted to the channel).

2. Model-side invariant (prompt). Add to SOUL/system: "When you choose silence in a group chat, produce an empty text response with no reasoning tokens spent on the reply; if you produce reasoning, you must produce visible text." This makes the two branches consistent but doesn't fully fix the loop if the model still emits reasoning.

3. Transcript surfacing. When the empty-retry loop terminates, append a short system-role note into the next turn's context: "Your previous turn in thread X returned empty after N retries — check your group-chat rules if this was unintentional." Cheap, diagnosable, and recovers agency for the model.

Fix (1) is the cleanest — it aligns gateway retry semantics with the already-computed addressing state.

Related

  • 2026-04-13: Anthropic adapter thinking-only blocks on mid-session model switch
  • Earlier today (2026-04-20): over-reinforced group silence causing internal no-reply

Filed by Kaito on Waseem's behalf.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — major feature broken, no workaroundcomp/agentCore agent loop, run_agent.py, prompt buildercomp/gatewayGateway runner, session dispatch, deliveryplatform/slackSlack app adaptertype/bugSomething isn't working

    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