[BUG] Cowork: plugin-scoped Stop hook silently stops firing mid-session while user-scope hooks continue in the same session
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?
Filing as a fresh data point rather than a comment on #27398 — that issue describes plugin hooks never firing at all in Cowork due to --setting-sources user, which is a different failure mode. In our case the plugin-scoped Stop hook fired reliably, then went silent mid-session while user-scope hooks in the same session kept working normally.
Symptom
A plugin-scoped Stop hook stopped firing mid-session after what appears to have been a plugin-registry reload. It had been firing reliably until 2026-04-20T23:27:22Z, then went completely silent for the remaining ~75 minutes of the session despite many normal turn completions. The hook simply stopped being invoked — no errors, no skips, no warnings.
Differential (rules out script, interpreter, and state)
- The same script, interpreter, and state directory continued firing normally when registered through
~/.claude/settings.jsonhooks (UserPromptSubmit,SessionStart, and aSessionEndprobe) during the same window. - Transcript content did not materially change between pre-reload and post-reload turns, so this does not appear to be a content-driven skip condition.
- The plugin hook script writes one line per invocation (
OK/ERR/SKIP) to a capture log outside the sandbox. The log shows a clean 75+ minute gap starting at the reload point.
The failure appears to be in plugin-scoped hook dispatch, specifically after a mid-session registry reload. User-scoped hook dispatch continued working normally in the same session.
Environment note: this is a Cowork Desktop (macOS) bug, not a Claude Code CLI bug. The plugin is registered via hooks/hooks.json; an identical script is also registered via user-scope ~/.claude/settings.json as an A/B control, and the user-scope copy kept firing during the same window.
What Should Happen?
The plugin-scoped Stop hook should continue firing on every turn completion for the duration of the session, consistent with user-scope hook dispatch (which remained functional in the same session). If a mid-session plugin-registry reload is expected to affect hook dispatch, that behavior should be documented and logged, not silent.
Error Messages/Logs
No errors are emitted. The hook simply stops being invoked — no stderr output, no ERR/SKIP ledger lines, no warnings in the Cowork session log. The absence of any error or log line at the point of the silent stop is itself a significant data point.
Steps to Reproduce
- Install a Cowork plugin that registers a
Stophook viahooks/hooks.json. - Run a long Cowork session (>60 minutes) that triggers the hook on every turn.
- Observe the hook's invocation log: it will fire on every turn until some mid-session event (plugin registry reload), then go silent for the rest of the session.
- Confirm the differential by registering the same command as a user-scope hook in
~/.claude/settings.json— it keeps firing during the same window. - Compare hook-invocation timestamps in the plugin's log vs. the user-scope log across the boundary — the plugin log has a clean multi-turn gap; the user-scope log does not.
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
N/A — Cowork Desktop (macOS); this is a Cowork bug, not a Claude Code CLI bug. See body for environment.
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Other
Additional Information
Related issues (different failure modes, same neighborhood)
- #27398 — plugin hooks never discoverable in Cowork (closed as duplicate). Different failure mode — ours fires first, then stops.
- #10225 — UserPromptSubmit plugin hooks match but never execute. Different failure mode ("never" vs our "stops").
- #16047 — hooks stop executing after ~2.5 hours (Windows, affects all hooks). Similar shape, but our case shows user-scope hooks kept firing while plugin-scope went silent in the same session on macOS.
Workaround currently in use
Multi-trigger capture design registered through user-scope ~/.claude/settings.json (Stop, UserPromptSubmit, SessionStart orphan-scan, plus SessionEnd probe) with a local ack-aware JSONL ledger (pending, acked, dead_letter states) to prevent duplicates across trigger points. Retry sweep runs at the top of every hook invocation; pending items older than a configurable threshold are respawned, and dead-lettered after a max-attempts cap. This works around the plugin-scope dispatch issue entirely.
Happy to share plugin source, capture log excerpts, or hook spawn commands if useful for diagnosis.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗