[BUG] Task subjects leak via spinner UI and context re-injection

Resolved 💬 1 comment Opened Apr 26, 2026 by batchprocess128 Closed May 28, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The task primitive (TaskCreate / TaskUpdate) interacts with two adjacent design choices in a way that leaks user-defined task subjects into both the terminal UI and the model's context, with no user-facing suppression mechanism. Three issues compound:

  1. The system-reminder hook fires on a heuristic (apparently elapsed time + pending-task count, not user intent) and re-pastes the full task list (subjects + statuses) into model context every firing.
  2. The terminal spinner renders task subjects + counts during normal model-thinking time, indistinguishable from active in-progress work.
  3. activeForm strings persist in the UI render cache after a task transitions out of in_progress, until the next overwrite.

Task subjects routinely contain private content because TaskCreate documentation invites descriptive titles. Realistic subjects can include proprietary code references, internal project names, credential identifiers, personal information, or other user-private content. The interaction surfaces that content visibly in the terminal (physical observers, screen-share, screenshots) and repeatedly in model context (input-token cost; visible in JSONL logs the user may share for debugging).

Fixable at the primitive layer.

What Should Happen?

| | Expected | Actual |
|---|---|---|
| Hook firing | Suppress on user stop-signals for ≥5 turns | Fires on heuristic regardless of user intent |
| Hook payload | Count or flag (model can call TaskList) | Full task list every firing |
| Spinner UI | Render task subjects only when task is in_progress | Renders during all model-thinking |
| activeForm cache | Invalidate on status transition out of in_progress | Persists until next overwrite |
| User suppression | Slash command + settings.json toggle | None |

Error Messages/Logs

Example system-reminder block from JSONL session log (firing autonomously,
unrelated to model task-tool usage in the prior turn):

  <system-reminder>
  The task tools haven't been used recently. If you're working on tasks that
  would benefit from tracking progress, consider using TaskCreate to add new
  tasks and TaskUpdate to update task status (set to in_progress when starting,
  completed when done). Also consider cleaning up the task list if it has
  become stale. Only use these if relevant to the current work. This is just
  a gentle reminder - ignore if not applicable. Make sure that you NEVER
  mention this reminder to the user

  Here are the existing tasks:

  #1. [completed] <task subject>
  #2. [pending] <task subject — may contain user-private content>
  #3. [pending] <task subject — may contain user-private content>
  ... etc
  </system-reminder>

Steps to Reproduce

  1. Open Claude Code in a bare terminal (e.g., Apple Terminal.app — bug surfaces most clearly there).
  2. Initiate a session where the model uses TaskCreate to plan multi-step work. Have it create 5+ tasks with realistic descriptive subjects (e.g., Refactor authentication middleware in user-service rather than Task 1). Bug surfaces most clearly when subjects are realistic.
  3. Mark some tasks in_progress, then transition back to pending (e.g., paused work).
  4. Continue the session for 20+ minutes with mixed work.
  5. Observe in the JSONL session log (~/.claude/projects/.../*.jsonl): system-reminder blocks containing the literal nudge text plus the full task list, firing on a clock independent of model task-tool usage.
  6. Observe in the terminal UI: spinner renders task subjects during model-thinking even when no task is in_progress. Stale activeForm strings persist after status transitions.
  7. As user, message the model "stop using tasks" / "kill the spinner". The hook continues firing on subsequent turns regardless. Have the model commit to no further TaskCreate / TaskUpdate usage. The hook still continues firing — confirms it is heuristic-driven, not gated on model behavior.

Visibility differs by terminal/IDE: most acute on bare terminals (Apple Terminal, gnome-terminal). IDE wrappers (VS Code, Cursor) and feature-rich terminals (Warp, Wave) may transform the spinner surface but retain the context-injection problem.

Claude Model

Opus

Is this a regression?

I don't know

Claude Code Version

2.1.119 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Impact

  • Privacy. Task subjects often contain private content. Spinner UI exposes them physically; context re-injection puts them in JSONL logs.
  • Operational. Persistent UI noise is indistinguishable from active work; adds error risk in flows involving adjacent destructive vs. reversible UI options.
  • Billing. Full task list × N firings × multi-hour sessions adds input-token cost.

JSONL session log available on request (will scrub user-private content first).

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗