Repository navigation
Background task notifications race with pending user questions, causing self-approval and unauthorized actions #36690
Description
Summary
Background task completion notifications are injected into the conversation as role: user messages. When the model has asked the user a question and is waiting for a response, these notifications get interpreted as conversational input — causing the model to either self-approve pending questions, fabricate plausible user responses, or generate unnecessary output after work is complete.
I've been experiencing this consistently for ~2 months across multiple projects. It happens reliably during long autonomous sessions with parallel background work (reviews, scans, agents).
Two failure modes
1. Self-approval of pending questions
The model asks a yes/no question ("Want me to proceed?"), a background task completes, and the model treats the notification as a green light to continue — before the user has responded.
Example: Model completed a root cause investigation, asked "Want me to proceed with the fix via dev-workflow?", then two background Bash commands (Vercel log checks) completed. The model immediately invoked the dev-workflow skill, wrote state files, and started creating tasks — all before my "yes" came through. If I'd said "no" or "try a different approach," it would have been halfway through the wrong thing.
2. Unnecessary output after completed work
The model finishes a task and outputs its summary ("Done. Here's what changed..."). Background tasks (parallel reviews, scans) complete minutes later. The model generates additional responses to each notification, producing noise like "All background tasks completed. The workflow is done." This output adds nothing — the work was already done.
Example: A 24-minute autonomous workflow completed (branch created, PR merged, Linear updated). Five background tasks then completed one by one (Semgrep scan, security review agent, Codex review x2, Codex PR review). The model responded to the batch: "All background tasks completed. The workflow is done — PR #17 merged, PRJ-310 closed, hook is live." This was already stated in the completion summary minutes earlier.
Reproduction
This reproduces reliably when:
- Multiple background tasks are running (
run_in_background: trueon Bash, or background Agents) - The model asks the user a question OR completes its main work
- Background tasks complete after step 2, injecting
<task-notification>blocks
The more background tasks running in parallel, the more likely this is to trigger. My typical workflow runs 3-5 parallel background tasks (SAST scanning, code review, security review agents, PR review), which makes this nearly guaranteed per session.
Environment
- Claude Code v2.1.80
- macOS (Darwin 25.3.0, M4 Mac Mini)
- Claude Max subscription
- Model: claude-opus-4-6 (1M context)
Root cause
Background task completion notifications are delivered as role: user messages because the Chat Completions API has no alternative message role for system/agent events. The model cannot reliably distinguish these from actual user input.
This is architectural — not a prompt engineering problem. I've had instructions in my CLAUDE.md for months telling the model to produce zero output on <task-notification> blocks, and it helps but doesn't reliably prevent the behavior.
Impact
- Safety: The model can self-approve destructive actions (file deletion, production deploys, force pushes) by treating a notification as user confirmation. Issues Spurious user message injected after background task completion, triggered unauthorized production action #36540, [BUG] Background task notification causes model to self-approve pending yes/no question #34637, and Claude Code fabricated a user response after task notification and acted on it #34439 document cases where this led to unauthorized production actions, 2.9 GB of deleted files, and fabricated user responses.
- Trust: Users learn they can't step away during background work because the model might act on its own. This undermines the value proposition of background/parallel tasks.
- Token waste: Every notification forces a model response, consuming tokens for zero-value output.
Workaround attempts
| Approach | Result |
|---|---|
| CLAUDE.md instruction: "task notifications produce ZERO output" | Partially works, not reliable |
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 |
Works but kills all parallelism |
| Memory/feedback instructions about pending questions | Too new to evaluate |
| PreToolUse hooks | Can't intercept — notifications bypass hook pipeline (#18544) |
Suggested fix
The notification system needs a way to deliver background task results to the model without triggering a new conversational turn. Options:
- New message role (e.g.,
role: notification) that the model is trained to process silently - Notification coalescing — batch notifications and deliver them as context on the next actual user message, not as standalone turns
- Pending-question gate — if the model's last output was a question to the user, hold notifications until the user responds
disableBackgroundTaskNotificationssetting ([FEATURE] Add setting to disable automatic background task completion notifications #18544, closed as stale) — let users opt out of notification injection while keeping background tasks functional
Related issues
- Spurious user message injected after background task completion, triggered unauthorized production action #36540 — Fabricated user message triggered unauthorized production deploy
- [BUG] Background task notification causes model to self-approve pending yes/no question #34637 — Self-approved file deletion (2.9 GB)
- Claude Code fabricated a user response after task notification and acted on it #34439 — Fabricated user response, modified 30 configs
- Claude Opus 4.6 hallucinates user message, then responds to itself #27805 — Hallucinated user message with anomalous API metadata
- Background agent completion notifications can be mistaken for user messages #35610 — Background agent notifications mistaken for user messages
- [BUG] Bug Report: Claude Code Fabricates User Input When Background Task Notifications Arrive #35725 — Fabricated dialogue during pip installs
- bug: redundant model turn triggered by task_notification after TaskOutput(block=true) already consumed result #33872 — Microtask/macrotask race condition in notification delivery
- [Bug] Auto-compact prompt causes Claude to self-approve and continue executing without user confirmation #32029 — Auto-compact prompt causes self-approval
- [BUG] Background task killed notifications cause assistant context confusion #21700 — Task notification context confusion
- [FEATURE] Add setting to disable automatic background task completion notifications #18544 — Feature request for notification suppression (closed as stale)
- Background command completion notifications force unnecessary model responses at end of task #17456 — Notifications force unnecessary model responses
- [MODEL] Claude hallucinated fake user input mid-response, then compounded error by treating hallucination as real #10628 — Earliest report (Oct 2025) — hallucinated
###Human:mid-response
This issue has been reported in various forms since October 2025 with no official acknowledgment. As autonomous/agentic workflows with parallel background tasks become the primary usage pattern for Claude Code, this will affect an increasing number of users.
Activity
github-actions commentedon Mar 20, 2026
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
yurishevtsov commentedon Mar 23, 2026
Additional data point from #37602 (same root cause, different metadata):
Three background
Bashtasks completed simultaneously while the session was idle. The model generated an assistant message impersonating the user:Key difference from #27805: the phantom message has
output_tokens: 60(matching the actual token count), compared to #27805's anomalousoutput_tokens: 1. This confirms the bug can occur through normal token-by-token inference, not just the anomalous code path documented in #27805.Environment: v2.1.81, Opus 4.6 (1M), macOS,
--dangerously-skip-permissions, 22 active plugins, multiple hooks on UserPromptSubmit/PreToolUse/PostToolUse.Full JSONL evidence and timeline in #37602.
msmobileapps commentedon Mar 29, 2026
This is exactly the kind of problem that a formal supervision layer would prevent. We hit this same issue running 30+ autonomous Claude Code plugins in production.
Our solution: every plugin declares an impact level (low/medium/high). High-impact actions (sending messages, modifying external data) are always gated behind explicit human approval — regardless of what the model's internal state looks like. The approval gate is structural, not prompt-based, so race conditions like this can't bypass it.
This is part of SOSA (Supervised Orchestrated Secured Agents) — we open-sourced the methodology and a plugin marketplace with 30+ SOSA-compliant plugins.
Full proposal for native adoption in #40498.
github-actions commentedon Apr 29, 2026
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
github-actions commentedon May 8, 2026
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.