[BUG] Hooks silently don't fire in Desktop app or new RC session slots (terminal & first RC session work)
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?
Hooks configured in a project's .claude/settings.json (SessionStart, Stop, PreToolUse, PostToolUse) fire reliably in two of four session-entry paths and silently fail to fire in the other two, on the same machine, same settings file, same repo:
| Path | Hooks fire? |
|---|---|
| claude in the terminal | Yes |
| claude rc / /rc — the first remote-control session on a connection | Yes |
| Claude Desktop app, Code tab | No |
| A new session slot opened within an already-existing remote-control connection | No |
This looks like the same underlying mechanism as two already-open issues, and I want to add corroborating evidence tying them together as one coherent pattern rather than isolated reports:
- #87657 — Desktop-app / Agent SDK entrypoint sessions intermittently load
Hooks: Found 0 total hooks in registrydespite settings declaring them. - #90798 —
WarmLifecyclepre-warms a session by spawning a throwaway backing CLI process (which fires its ownSessionStart), then attaches the visible session to a different, already-running process instead — so the slot the user actually types into never gets its own freshSessionStart. - #95339 — forked/new session slots reuse the parent's already-running process rather than spawning a fresh one, so process-start-bound behavior (there: RC auto-connect; here: hooks) never fires for them.
I can confirm WarmLifecycle is actively running on my machine while reproducing this — see log excerpt below — which is consistent with #90798's mechanism being the cause of the "new session slot inside an existing RC connection" failure, separately from whatever causes #87657's "0 hooks in registry" in the plain Desktop Code-tab case.
What Should Happen?
Per the hooks docs: "Claude Code fires the same hook events wherever it runs: sessions in the terminal, IDE extensions, the Desktop app, and cloud sessions." Hooks declared in .claude/settings.json should fire consistently regardless of which UI/entry path started the session.
Error Messages/Logs
No error is shown in any of the four cases — failure is silent, which is what makes it hard to diagnose (I initially suspected my own hook config).
Project .claude/settings.json used for reproduction (generated by a third-party tool's init routine, @drewpayment/mink, but the shape is a plain, unremarkable hooks config):
{
"hooks": {
"SessionStart": [
{ "matcher": "", "hooks": [{ "type": "command", "command": "mink session-start" }] }
],
"Stop": [
{ "matcher": "", "hooks": [{ "type": "command", "command": "mink session-stop" }] }
],
"PreToolUse": [
{ "matcher": "Read", "hooks": [{ "type": "command", "command": "mink pre-read" }] },
{ "matcher": "Edit", "hooks": [{ "type": "command", "command": "mink pre-write" }] },
{ "matcher": "Write", "hooks": [{ "type": "command", "command": "mink pre-write" }] }
],
"PostToolUse": [
{ "matcher": "Read", "hooks": [{ "type": "command", "command": "mink post-read" }] },
{ "matcher": "Edit", "hooks": [{ "type": "command", "command": "mink post-write" }] },
{ "matcher": "Write", "hooks": [{ "type": "command", "command": "mink post-write" }] },
{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "mink post-tool" }] },
{ "matcher": "Grep", "hooks": [{ "type": "command", "command": "mink post-tool" }] }
]
}
}
~/Library/Logs/Claude/main.log excerpt showing WarmLifecycle active during reproduction of the "new session slot within an existing RC connection" case:
[info] [WarmLifecycle:session] Initialized (arm=when-hidden)
[info] [WarmLifecycle:preview] Initialized (arm=when-hidden)
[info] [WarmLifecycle:preview] Starting idle timeout for local_<id>: 1800s
[info] [WarmLifecycle:preview] Warming up session local_<id>
Steps to Reproduce
- Add the hooks config above (or any
SessionStart/PreToolUsehook that logs to a file, for an unambiguous signal) to a project's.claude/settings.json. For debugging I've used a plainecho $(date) >> filecommand alongside theminkhook. Example:
``json``
"SessionStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "mink session-start"
}
]
},
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "echo \"PROJECT MINK SESSIONSTART $(date)\" >> claude-hook.log"
}
]
}
],
- Start
claudein a terminal in that project — confirm the hook fires (log line appears). - From that terminal session, run
/rcto start remote control — confirm the hook fires for that first remote session too. - From within an already-connected remote-control session, open an additional session slot in the same connection (mobile app "+" / new chat) — confirm the hook does not fire for that new slot, even though it fired for the first slot on the same connection.
- Other setting (independent from claude terminal/remot): Open the same project in the Claude Desktop app, Code tab — confirm the hook does not fire (no log line), and optionally run
/debugto check forHooks: Found 0 total hooks in registry.
Claude Model
Sonnet
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.267 (terminal CLI, via PATH). Desktop app bundled CLI reports required_version:2.1.270 internally; Desktop app itself is 2.110.0.
Platform
Claude Pro subscription
Operating System
macOS 26.6.2 (25G83)
Terminal/Shell
zsh
Additional Information
Related issues that each cover part of this pattern individually: #87657, #90798, #95339. Filing this to connect them as one reproducible matrix (terminal / first-RC-session work; Desktop / additional-RC-slot don't) rather than duplicate any of them — happy to have this closed as a dupe if a maintainer prefers to fold it into one of the three instead.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗