claude-code - 💡(How to fix) Fix [BUG] Long-CI-wait + Monitor: every poll forces an assistant response, turning the chat into a wall of '·' (compounding #50258 / #55400) [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#60630Fetched 2026-05-20 03:53:32
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Timeline (top)
labeled ×4commented ×1

Error Message

  1. <task-notification> should support a suppress_assistant_turn: true mode for streaming-status events. The notification gets logged into the transcript for context but does not consume a turn. Model only responds when there is something to respond to (e.g. error, completion, threshold trip).

Root Cause

A real session of ours just spent ~90 minutes of user-perceived dead air across two CI rounds (~13 min each plus a 3rd ~13 min retry after a CI hotfix), because every 20-30 s monitor tick consumed a turn. Filing this so other users hitting the same pattern can find it.

Fix Action

Fix / Workaround

Workaround Today

A real session of ours just spent ~90 minutes of user-perceived dead air across two CI rounds (~13 min each plus a 3rd ~13 min retry after a CI hotfix), because every 20-30 s monitor tick consumed a turn. Filing this so other users hitting the same pattern can find it.

Code Example

# Wait for a GitHub Actions CI run (~13 min)
Monitor({
  description: \"CI run X\",
  timeout_ms: 1_500_000,
  persistent: False,
  command: '''
    while true; do
      s=$(gh run view 12345 --json status,conclusion,jobs)
      ts=$(date -u +%H:%M:%SZ)
      step=$(echo \"$s\" | jq -r '.jobs[].steps[]? | select(.status==\"in_progress\") | .name' | head -1)
      echo \"[$ts] CI=$(echo \"$s\" | jq -r .status) step=$step\"
      [ \"$(echo \"$s\" | jq -r .status)\" = \"completed\" ] && break
      sleep 20
    done
  '''
})
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • Searched existing issues; this is a concrete reproducer that compounds #50258 and #55400
  • Single bug report
  • Latest Claude Code (v2.1.144)

What's Wrong?

When using Monitor to watch a long-running external job (e.g. ~13 min GitHub Actions CI run) with a 20–30 s poll interval, every tick fires a <task-notification> that is treated as a user turn the model must respond to. The chat becomes dominated by ~30 notification blocks plus ~30 assistant responses, even though only the start, step transitions, and completion convey real signal. The intermediate ticks are noise that the model cannot suppress.

The combinatorial UX failure mode of #50258 (Monitor floods) + #55400 (harness blocks can't be hidden) + this turn-structure forcing:

  1. Monitor emits one stdout line per poll → one <task-notification> per tick (#50258).
  2. The notification is rendered as a chat-bubble in the UI with no collapse option (#55400).
  3. Each notification is fed to the model as a fresh user turn — the model has no "no response needed" marker, so it produces something. Either:
    • Echoes the status (annoying repetition that drowns out real updates)
    • Sends a placeholder like · (looks broken / the model "ignoring" the user)
    • Fabricates a Human: turn (#60360 — model fills the gap)

End user perception: the assistant looks frozen / unresponsive / spammy for 5–15 minutes at a time, even though everything is technically working. Forces the user to type "watch it run" repeatedly just to keep the assistant engaged, which itself adds turns to the transcript.

What Should Happen?

Any of the following would close the gap. They are listed in order of expected effort/impact:

  1. Monitor should accept a notify: \"on_completion\" | \"on_change\" | \"every_line\" parameter (default on_change), so polling loops naturally emit only step transitions instead of every iteration.
  2. <task-notification> should support a suppress_assistant_turn: true mode for streaming-status events. The notification gets logged into the transcript for context but does not consume a turn. Model only responds when there is something to respond to (e.g. error, completion, threshold trip).
  3. At the CLI/UI layer, add a settings.json toggle (per #55400) that visually collapses <task-notification> bubbles into a single rolling status line. Even without (1) or (2), this drops the visual noise.

Today there is no notify-style knob and no UI suppression, so the polling pattern is structurally noisy.

Concrete Reproducer

# Wait for a GitHub Actions CI run (~13 min)
Monitor({
  description: \"CI run X\",
  timeout_ms: 1_500_000,
  persistent: False,
  command: '''
    while true; do
      s=$(gh run view 12345 --json status,conclusion,jobs)
      ts=$(date -u +%H:%M:%SZ)
      step=$(echo \"$s\" | jq -r '.jobs[].steps[]? | select(.status==\"in_progress\") | .name' | head -1)
      echo \"[$ts] CI=$(echo \"$s\" | jq -r .status) step=$step\"
      [ \"$(echo \"$s\" | jq -r .status)\" = \"completed\" ] && break
      sleep 20
    done
  '''
})

The user sees ~40 nearly-identical notification bubbles in the transcript with ~40 model responses, of which only the first/last/step-transition ones are useful. The intermediate 30+ responses are repetition that the user reads as 'broken'.

Workaround Today

Skip Monitor entirely. Use ONE Bash with run_in_background: true running the whole pipeline (poll → react → next-stage) and write structured output to a logfile. Then Read the logfile only when needed. The trade-off is no streaming visibility, which is exactly the use-case Monitor is supposed to serve.

System Info

  • Claude Code v2.1.144 (Linux x64 musl)
  • Session: long-running iteration on a live trading bot, CI + restart + verify pipeline
  • Related open: #50258, #55400, #60360, #58852

Self-Reported Friction

A real session of ours just spent ~90 minutes of user-perceived dead air across two CI rounds (~13 min each plus a 3rd ~13 min retry after a CI hotfix), because every 20-30 s monitor tick consumed a turn. Filing this so other users hitting the same pattern can find it.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] Long-CI-wait + Monitor: every poll forces an assistant response, turning the chat into a wall of '·' (compounding #50258 / #55400) [1 comments, 2 participants]