PreToolUse hook silently stops firing mid-session and never recovers; concurrent session unaffected

Status Open
Reported on v2.1.238
Maintainer reply None cached
Activity 0 comments · opened Aug 22, 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?

In one ordinary interactive session, the PreToolUse hook stopped being invoked. Not for one tool and not for one call: from a definite instant onward, every write-class tool call in that session ran with no hook invocation, and the session never recovered. A second session running concurrently in the same project, against the same settings file, stayed hooked throughout. No error was surfaced anywhere, and nothing was written to the hook's stderr file.

The hook in question is a Python script registered as a single PreToolUse entry in the project-scoped <project-dir>\.claude\settings.json. It gates write operations to a set of protected paths and appends exactly one line to a log file on every invocation, allow or deny. That per-invocation line is what makes the outage measurable. The hooks block exists in that one settings file only; the user-scope settings files carry no hooks key. <project-dir> is on a Google Drive File Stream (DriveFS) virtual volume, while the hook script itself is on a local NTFS volume.

Every non-sidechain Bash / PowerShell / Edit / Write tool call in three sessions on 2026-08-21 was correlated against the hook's log, matching on tool name within −2 s to +10 s and filtering on target path.

| Session | Window (UTC) | Tool calls | Calls with no hook log line | Behaviour |
|---|---|---|---|---|
| e4439989 | 11:23 onward | 42 | 0 | fully hooked throughout |
| 182e3364 | 21:42–21:57 (concurrent) | 28 | 1 (21:44:14, recovered by 21:44:42) | one transient miss |
| 0598abf9 | 16:16–21:57 | 52 | 19 | 100% hooked through 19:32:44; 0% from 21:43:00 to session end |

In 0598abf9, the last hooked call is 19:32:44 and the first missed call is 21:43:00. There is no partial degradation between them and no recovery after. The 19 missed calls include PowerShell, Bash and Edit, so this is not specific to one tool. During the same wall-clock window, session 182e3364 was logging hook invocations normally.

One caution on method, for anyone reproducing the analysis: a coarse timestamp-only correlation scored one late call in 0598abf9 as hooked. It was not. The nearby log line belonged to the concurrent session writing a different file. Tool-name plus path-filtered correlation shows the outage unbroken to the end of the session.

The core question this issue is asking: can a session lose its PreToolUse hook registrations mid-flight in v2.1.238?

Concretely:

  1. Is there a known code path by which a live session drops or invalidates its hook registrations without terminating and without surfacing an error?
  2. Is the settings file re-read during a session, and if so, what is the behaviour when the file is momentarily unreadable or is served from a virtual filesystem such as DriveFS?
  3. Is hook registration state recorded per session anywhere a user can inspect after the fact, so a session like 0598abf9 can be diagnosed rather than inferred from log absence?
  4. Is there any supported way for a session to detect that its own hooks are no longer being invoked? At present the failure is silent by construction: a hook that stops running looks exactly like a hook that is allowing everything.

Session IDs 0598abf9, 182e3364 and e4439989 are included in case they can be correlated against telemetry on your side.

What Should Happen?

A registered PreToolUse hook is invoked for every matching tool call for the life of the session. If a registration is lost, or the hook cannot be launched, that failure is surfaced visibly rather than presenting as silent non-invocation.

Error Messages/Logs

There are no error messages. That is the substance of the report: the failure produced no output anywhere. What follows is the evidence of absence.
# 1. The hook's own log has a clean hole across the outage window.
#    Both surviving lines belong to the CONCURRENT session (182e3364), not to 0598abf9.

16318:2026-08-21T21:46:14.796885 | Write | <file-a> | allow:non-protected
16319:2026-08-21T21:50:21.517308 | Edit  | <file-a> | allow:non-protected


# 2. Inside that hole, session 0598abf9 executed the following, from its transcript.
#    Every one of them matches the PreToolUse matcher. None produced a log line.

  21:48:43  PowerShell  file-existence test                 -> no hook log line
  21:48:48  PowerShell  script invocation                   -> no hook log line
  21:48:52  PowerShell  Copy-Item (overwrite a file)        -> no hook log line
  21:49:09  PowerShell  Remove-Item                         -> no hook log line
  21:49:34  PowerShell  Copy-Item (overwrite a file)        -> no hook log line
  21:49:51  PowerShell  python <script>  (x3, to 21:50:05)  -> no hook log line
  21:50:16  Bash        echo                                -> no hook log line
  21:50:47  Bash        git add -A && git commit            -> no hook log line
  21:51:13  Bash        git push                            -> no hook log line

#    Note that Bash and Edit are in that list. This is not a PowerShell phenomenon.


# 3. The hook's stderr file was never touched.
#    The registration redirects the hook's stderr to this file with 2>>.
#    A Python traceback, a missing interpreter, or a shell launch failure
#    would each have landed there.

    stderr file mtime: 2026-07-03 06:25   (i.e. seven weeks before the outage; unchanged)

#    Conclusion: the hook process was not executed at all. It did not run and fail.


# 4. The transcript's stop_hook_summary records carried an empty error array throughout.

    "hookErrors": []

#    Weak evidence in both directions: the transcript records no equivalent
#    summary for PreToolUse, so this absence proves little on its own.


---

Steps to Reproduce

This has not been reproduced on demand. No reliable recipe is offered, and none should be inferred from what follows. These are the conditions observed around the one occurrence, stated as observations.

  • A single interactive session, running normally, with one PreToolUse hook registered in project-scoped settings and matching several tool names.
  • The session was long-running: roughly 5 hours 40 minutes from start to the end of the transcript, with substantial subagent activity in the hours before the outage.
  • The session was idle for roughly 130 minutes immediately before the first missed call. Idle time alone does not explain it: the same session had earlier idled roughly 124 minutes, and the next call after that idle was hooked normally.
  • The settings file carrying the hooks block was not modified during the session. Its mtime is 2026-08-21 04:05:03 local, before the session started at 10:16 local.
  • The settings file lives on a DriveFS virtual volume, not on local disk.
  • A second session was running concurrently in the same project against the same settings file, and it stayed hooked. It had one transient miss at 21:44:14 that recovered by 21:44:42.
  • Once the outage began, it never lifted for the remainder of the session.

What would be needed to catch it in the act: a session caught in the failed state while debug output is being captured, so that hook registration state can be inspected at the moment of failure rather than inferred afterwards from the absence of log lines. Any per-session record of hook registration state, or any way to query the live registrations from inside a running session, would make this diagnosable.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.238

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

VS Code integrated terminal

Additional Information

Related, but distinct. Existing reports of PreToolUse hooks not firing that I could find are context-dependent: they concern non-interactive modes (--print) or background execution (--bg), where hooks never fire for that invocation at all. This report is different in kind. This is an ordinary interactive session in which hooks fired correctly 33 times and then stopped part-way through, permanently, with a concurrent interactive session in the same project unaffected. If those reports are the same underlying defect, the connection is not visible from the outside.

The closest one I found is #88328 (PermissionRequest hooks never firing in --print mode on 2.1.237, while a PreToolUse hook in the same settings file fires normally). Other open reports concern hook decisions being discarded in background sessions rather than the hook failing to run, which is a different failure again.

What was ruled out, and how.

  • Matcher or tool-name mismatch. The affected tool names are present in the PreToolUse matcher, and the same tools were hooked normally in 1,447 log lines, including two denials earlier the same day at 11:17:04 and 16:00:58.
  • Hook crash, missing interpreter, or launch failure. Covered in the logs field above. The registration redirects stderr with 2>>; that file has been untouched since 2026-07-03. The process was not executed at all.
  • A hook decision defect. The exact command strings were recovered from the session transcript and replayed through the hook's decision function. It denies them. The hook did not permit these writes; it never saw them.
  • Mid-session change to the settings file. Its mtime predates the session start by six hours.
  • Long idle, on its own. Covered in the reproduction field: an earlier 124-minute idle in the same session was followed by a normally hooked call.
  • Hook timeout. Weak. The calls after 21:43:00 are 4–6 seconds apart, showing no 60 s stalls, and the stop_hook_summary records carried an empty hookErrors array throughout.

What was not established. The ultimate cause. The non-invocation was not reproduced, and two candidates survive the evidence above. They are not ranked here, and I am not choosing between them:

  1. CLI-internal loss of the PreToolUse registration for that session. This fits the shape of the failure: abrupt, total, session-scoped, permanent, tool-agnostic, no error surfaced.
  2. A settings re-read or hook invalidation driven by the DriveFS virtual volume, on which the hooks block lives. A re-materialisation or brief unavailability could cause the settings to be re-read and the hooks dropped without changing the file's mtime. The only corroboration is timing: the concurrent session had its own single transient miss at 21:44:14, inside the same few minutes.

Separating these requires a session caught in the failed state with debug output running, which has not happened.

View original on GitHub ↗