UserPromptSubmit hook not invoked when prompt contains an attachment (VSCode extension) — distinct from #58269

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

The UserPromptSubmit hook is silently bypassed when a prompt contains an image/file attachment, but only in the VSCode extension. The hook fires normally for plain-text prompts in the same session. Because the hook is never invoked for attachment-bearing prompts, any prompt-validation logic (including block decisions) is completely skipped, and the prompt reaches the model as if no hook were configured.

What Should Happen?

The UserPromptSubmit hook should fire for every user-submitted prompt regardless of whether the prompt has attachments. The JSON payload piped to the hook on stdin should also include structured metadata about attachments (e.g., an attachments or content_blocks array with type/path/mime), so validator hooks can inspect them. At minimum, the hook must fire and receive the text portion, so decision: "block" and other outputs are honored.

Error Messages/Logs

No error is produced. The hook is silently skipped.

Captured stdin payload from a plain-text prompt (hook DOES fire):
{
  "session_id": "cd5a5d53-c7b6-450d-bf74-4922d2f72c4c",
  "transcript_path": "C:\\Users\\NaveenSathiyaMoorthi\\.claude\\projects\\...\\cd5a5d53-c7b6-450d-bf74-4922d2f72c4c.jsonl",
  "cwd": "n:\\ClearGRC\\cleargrc-api",
  "permission_mode": "acceptEdits",
  "hook_event_name": "UserPromptSubmit",
  "prompt": "should i restart for the validate-prompt.ps1 file changes to take effect in this current session"
}

For a prompt with an image attached: no payload is captured, no log entry, no
hook invocation. Debug capture line in the hook script confirms stdin was
never opened by Claude Code.

Steps to Reproduce

Register a global UserPromptSubmit hook in ~/.claude/settings.json:

"hooks": {
"UserPromptSubmit": [{
"hooks": [{
"type": "command",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"C:\\Users\\<user>\\.claude\\hooks\\capture.ps1\"",
"timeout": 15
}]
}]
}
Create capture.ps1 that dumps stdin to a log file and exits 0:

$raw = [Console]::In.ReadToEnd()
Add-Content -Path "$env:USERPROFILE\.claude\logs\hook-payload.json" -Value "=== $(Get-Date -Format o) ===n$rawn"
exit 0
Open the Claude Code VSCode extension chat panel.
Submit a plain-text prompt, e.g. hello. Confirm the payload is appended to hook-payload.json.
In the same session, attach an image (paste screenshot) and submit fix the bug. Observe that no new entry is appended to hook-payload.json — the hook was never invoked.
Bonus: register a Deny branch in the script that returns {"decision":"block","reason":"blocked"} on stdout and exit 0. It correctly blocks plain-text prompts but is never consulted for attachment-bearing prompts.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.227 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Other

Additional Information

  • Not a duplicate of #58269 — that report is about the extension failing to render hook stdout in the chat panel. This report is about the hook not being invoked at all for prompts with attachments; the payload-capture script confirms stdin is never opened. Block decisions are therefore silently ignored, which is a security-relevant regression for validator hooks.
  • The UserPromptSubmit payload has no field describing attachments. Even after fixing invocation, a validator hook cannot inspect what was attached. Adding an attachments or content_blocks array with {type, path, mime, size} entries would let validator hooks make informed block decisions.

CLI behavior (control): the hook fires correctly for both plain-text and (as far as CLI supports) attachment-referencing prompts. The bypass appears to be extension-specific.
Two related shortcomings discovered while debugging this:
The current UserPromptSubmit payload has no field for attachments. Adding an attachments/content_blocks array with {type, path, mime, size} entries would let validator hooks make informed block decisions.
When a UserPromptSubmit hook returns {"decision":"block","reason":"..."} (JSON stdout path), the CLI renders the reason visibly to the user, but the VSCode extension chat panel appears to render nothing — the input just vanishes. Users cannot tell why their prompt did not process. Whether this is the same bug or a separate rendering gap in the extension is unclear; either way, a visible block reason would be a big UX improvement.
Reproducible on:
OS: Windows 11 Pro 10.0.26200
PowerShell: (whatever $PSVersionTable.PSVersion reports)
Claude Code VSCode extension: (latest installed as of 2026-08-10)

View original on GitHub ↗