UserPromptSubmit hooks permanently stop firing for a session, correlated with a duplicate generate_session_title request
Bug: UserPromptSubmit hooks permanently stop firing for a session, correlated with a duplicate generate_session_title request
Environment
- Claude Code version: 2.1.247
- Entrypoint:
claude-vscode(VS Code extension) - Platform: macOS
- Hooks configured via project-level and user-level
settings.json, standard format (no custom tooling beyond ordinary shell/Python scripts)
Summary
In four separate sessions observed today, every UserPromptSubmit hook stopped firing entirely, for the whole lifetime of the session, while SessionStart, PreToolUse, PostToolUse, and Stop hooks on the same session continued to work normally. One affected session ran 999 PreToolUse events and 17 Stop events with zero UserPromptSubmit events across its entire history.
This is not a hook configuration problem — the same settings.json is shared by dozens of concurrently-running sessions, and the large majority are unaffected. It also is not a case of the hook scripts failing: the extension host log shows the scripts running, producing valid JSON, and being logged as "provided additionalContext," but the resulting hookSpecificOutput never appears in the session's own persisted transcript, and no further UserPromptSubmit hook activity of any kind occurs for that session afterward.
Reproducible signature found in the extension host log
Searching ~/Library/Application Support/Code/logs/*/window*/exthost/Anthropic.claude-code/Claude VSCode*.log, every affected session shows this exact pattern immediately after the last UserPromptSubmit hook script logs success:
[DEBUG] [API REQUEST] /v1/messages ... source=generate_session_title
[DEBUG] [API REQUEST] /v1/messages ... source=generate_session_title
Two generate_session_title requests fire within roughly 100ms of each other — a duplicate of what is normally a single request. Immediately after this, a source=sdk request follows (the actual conversational turn).
Checked across every log segment covering today's activity (roughly 30 concurrent sessions, spanning many hours): exactly four sessions show this doubled generate_session_title request, and all four are the ones with zero UserPromptSubmit hook activity for their entire lifetime. No session without the doubled request shows the missing-hooks symptom, and no session with the doubled request has working UserPromptSubmit hooks. All four are otherwise ordinary sessions — no unusual project configuration, no unusual hook scripts, same Claude Code version as every working session alongside them.
Working hypothesis (unconfirmed — I have no visibility into extension internals)
The duplicate generate_session_title request appears to race with the real turn's request for whatever mechanism attaches pending hook context to an outgoing API call. If the hook context gets attached to the throwaway title-generation request instead of the real one, and the session is then marked as having already "delivered" that hook context, this would explain both symptoms: the content is generated and logged as sent, but never reaches the model, and the condition persists for the rest of the session rather than self-correcting on the next turn.
This would mean the bug is specific to a session's first turn (since title generation typically happens once, from the first message), with the effect on UserPromptSubmit hooks persisting afterward due to some sticky "already handled" state.
Impact
Any hook registered on UserPromptSubmit — at the user level or project level — silently and permanently stops running for an affected session, with no error surfaced anywhere the user would see it. The only way we found to detect it was inspecting the extension's own debug log for the specific double-request signature above; there is no indication inside Claude Code itself (no error, no warning, nothing in the transcript) that this occurred.
What would help
- Confirmation of whether
generate_session_titleand the first real turn's request can race for a shared hook-context-attachment step, and whether that's the actual mechanism here. - If so, either serializing that attachment against concurrent requests, or re-attempting hook delivery on the next turn if it wasn't confirmed delivered, would resolve it.
- Happy to provide further log excerpts (with identifiers scrubbed) if useful for reproduction — the pattern above should be independently searchable in any user's own extension host log.