UserPromptSubmit hooks still never fire in the VS Code extension (2.1.263, Windows) — ref #15021

Status Open
Reported on v2.1.260
Maintainer reply None cached
Activity 0 comments · opened Sep 7, 2026

Summary

UserPromptSubmit hooks configured in ~/.claude/settings.json never fire in the VS Code native extension (entrypoint: claude-vscode). The same hook, same settings file, same machine, same user and same cwd fires reliably in a non-IDE host.

This is #15021, closed as not planned in February 2026 against 2.0.75 / macOS. I'm filing a fresh data point because it still reproduces on 2.1.260 and 2.1.263 on Windows 11, and because the failure is silent: no warning, no log line, and the limitation isn't documented, so it is only discoverable much later by noticing that data is missing.

Reproduction

~/.claude/settings.json:

{
  "hooks": {
    "UserPromptSubmit": [
      { "hooks": [ { "type": "command", "command": "py <path>/prompt_logger.py" } ] }
    ]
  }
}

The hook appends one JSON line per prompt to a file.

  • Non-IDE host: every prompt recorded (115 records accumulated normally).
  • VS Code extension: zero records, across an entire multi-day session with 22 prompts.

Ruled out locally before filing:

  • the interpreter resolves on PATH and the hook script is trivially correct (it demonstrably works for the other host);
  • project-level .claude/settings.json contains only permissions — no hook override;
  • identical cwd to sessions that do record, so the working directory is not the discriminator.

Why this matters beyond convenience

UserPromptSubmit is the documented mechanism for prompt-level logging and auditing. Because it fails silently in this host, anything built on it yields an incomplete record that looks complete. In my case a prompt log fed a periodic work summary, and an entire multi-day session was simply absent from it — the gap was noticed only by chance, days later.

Ask

Either:

  1. hook parity for the IDE host; or
  2. failing that, document the limitation on the hooks and VS Code extension pages, and ideally surface it at runtime — e.g. a one-time notice when a session starts in a host that will not execute the hooks it can see configured.

A docs-only change would have prevented the whole investigation.

Workaround, for anyone who lands here

The extension does write a full per-session transcript to disk:

~/.claude/projects/<slugified-cwd>/<session-id>.jsonl

(the slug being the cwd with every non-alphanumeric character replaced by -), so prompts can be recovered after the fact. The human-typed prompts are the records with type == "user" and origin.kind == "human". That pair matters: tool results, subagent/sidechain traffic, task notifications and assistant-scheduled prompts all also arrive as type: "user", and origin.kind is what separates them. Host-injected <ide_opened_file> / <system-reminder> blocks need stripping from the text to get what the user actually typed.

Environment

  • Claude Code 2.1.260 → 2.1.263, entrypoint: claude-vscode
  • Windows 11
  • Same ~/.claude/settings.json produces working hooks in a non-IDE host on the same machine

View original on GitHub ↗