Preflight Checklist
What's Wrong?
The built-in idle notification (notification_type: idle_prompt, "Claude is waiting for your input") fires roughly 60 seconds after the main agent ends a turn, even when that turn ended only to wait on background subagents launched via the Agent tool. In a long subagent-driven task the main agent ends a turn every time it dispatches agents, so preferredNotifChannel: terminal_bell / iterm2_with_bell rings repeatedly while the task is nowhere near done.
The Stop hook payload already carries a background_tasks array with per-task status: "running", so Claude Code knows the session is still busy at the moment the idle timer starts. The notification path doesn't consult it.
What Should Happen?
idle_prompt should not fire while any entry in background_tasks has status: "running". It should fire once the main agent is idle with no background work in flight, or when it is genuinely blocked on the user (question, permission prompt).
Alternatively, a distinct notification type (e.g. waiting_on_background_tasks) would let a Notification hook filter it.
Error Messages/Logs
Logging-only Notification hook, session on ttys000 running a long subagent task the whole time:
2026-09-11 10:44:31 tty=ttys000 pid=18275 cwd=/Users/brianbyrne/projects/react_office {"notification_type":"idle_prompt","title":null,"message":"Claude is waiting for your input"}
2026-09-11 11:03:23 tty=ttys000 pid=18275 cwd=/Users/brianbyrne/projects/react_office {"notification_type":"idle_prompt","title":null,"message":"Claude is waiting for your input"}
2026-09-11 11:15:42 tty=ttys000 pid=18275 cwd=/Users/brianbyrne/projects/react_office {"notification_type":"idle_prompt","title":null,"message":"Claude is waiting for your input"}
Stop hook payload from the same build, captured with one agent in flight (shows the data is available):
{"background_tasks":[{"id":"a4b841ea0674abcb1","type":"subagent","status":"running","description":"Sleep to hold a background task open","agent_type":"general-purpose"}],"session_crons":[],"permission_mode":"bypassPermissions"}
Steps to Reproduce
- In ~/.claude/settings.json set "preferredNotifChannel": "terminal_bell" (or "iterm2_with_bell").
- Optionally add a logging Notification hook:
"Notification": [{"hooks": [{"type": "command", "command": "jq -c '{notification_type, message}' >> ~/.claude/notif.log"}]}]
- Start a task that launches background subagents taking longer than 60 seconds each, e.g. "Use the Agent tool to research X, Y and Z in parallel, then summarize."
- Wait. Each time the main agent ends a turn to wait on agents, a bell / idle_prompt notification fires ~60s later while the agents are still running.
- Compare with a Stop hook that dumps
.background_tasks: it reports status "running" for those agents at the moment the turn ended.
Claude Model
Other
Is this a regression?
I don't know
Last Working Version
No response
Claude Code Version
2.1.268 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
Model: claude-fable-5-1[1m]
Related: #87351 reports the same noise from the desktop app and asks for an 'attention needed or finished' mode. This report shows the CLI already has the data to implement that: the Stop hook payload's background_tasks carries status: "running" at the moment the idle timer starts.
Workaround in use: set preferredNotifChannel to notifications_disabled and ring the bell from a Stop hook only when [.background_tasks[]? | select(.status == "running")] | length == 0, plus a Notification hook that ignores idle_prompt. This works, which is what shows the fix is feasible on the notification side. Note hook processes have no controlling tty, so the hook has to write BEL to the parent process's tty (ps -o tty= -p $PPID).
Preflight Checklist
What's Wrong?
The built-in idle notification (
notification_type: idle_prompt, "Claude is waiting for your input") fires roughly 60 seconds after the main agent ends a turn, even when that turn ended only to wait on background subagents launched via the Agent tool. In a long subagent-driven task the main agent ends a turn every time it dispatches agents, sopreferredNotifChannel: terminal_bell/iterm2_with_bellrings repeatedly while the task is nowhere near done.The Stop hook payload already carries a
background_tasksarray with per-taskstatus: "running", so Claude Code knows the session is still busy at the moment the idle timer starts. The notification path doesn't consult it.What Should Happen?
idle_promptshould not fire while any entry inbackground_taskshasstatus: "running". It should fire once the main agent is idle with no background work in flight, or when it is genuinely blocked on the user (question, permission prompt).Alternatively, a distinct notification type (e.g.
waiting_on_background_tasks) would let a Notification hook filter it.Error Messages/Logs
Logging-only Notification hook, session on ttys000 running a long subagent task the whole time: 2026-09-11 10:44:31 tty=ttys000 pid=18275 cwd=/Users/brianbyrne/projects/react_office {"notification_type":"idle_prompt","title":null,"message":"Claude is waiting for your input"} 2026-09-11 11:03:23 tty=ttys000 pid=18275 cwd=/Users/brianbyrne/projects/react_office {"notification_type":"idle_prompt","title":null,"message":"Claude is waiting for your input"} 2026-09-11 11:15:42 tty=ttys000 pid=18275 cwd=/Users/brianbyrne/projects/react_office {"notification_type":"idle_prompt","title":null,"message":"Claude is waiting for your input"} Stop hook payload from the same build, captured with one agent in flight (shows the data is available): {"background_tasks":[{"id":"a4b841ea0674abcb1","type":"subagent","status":"running","description":"Sleep to hold a background task open","agent_type":"general-purpose"}],"session_crons":[],"permission_mode":"bypassPermissions"}Steps to Reproduce
"Notification": [{"hooks": [{"type": "command", "command": "jq -c '{notification_type, message}' >> ~/.claude/notif.log"}]}]
.background_tasks: it reports status "running" for those agents at the moment the turn ended.Claude Model
Other
Is this a regression?
I don't know
Last Working Version
No response
Claude Code Version
2.1.268 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
Model:
claude-fable-5-1[1m]Related: #87351 reports the same noise from the desktop app and asks for an 'attention needed or finished' mode. This report shows the CLI already has the data to implement that: the Stop hook payload's background_tasks carries status: "running" at the moment the idle timer starts.
Workaround in use: set preferredNotifChannel to notifications_disabled and ring the bell from a Stop hook only when
[.background_tasks[]? | select(.status == "running")] | length == 0, plus a Notification hook that ignores idle_prompt. This works, which is what shows the fix is feasible on the notification side. Note hook processes have no controlling tty, so the hook has to write BEL to the parent process's tty (ps -o tty= -p $PPID).