[BUG] SessionStart hooks declared in MANAGED settings deliver no additionalContext in the desktop app on Windows; the same hook from user settings delivers, and managed settings deliver in the terminal CLI
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?
<html>
<body>
<!--StartFragment--><p dir="ltr">A <code>SessionStart</code> hook declared in <code>managed-settings.json</code> runs on every session start and writes valid JSON carrying <code>hookSpecificOutput.additionalContext</code> to stdout, but in the desktop app on Windows that text never reaches the model's context. The hook is not skipped: it has an observable side effect during the session, and its output parses.</p><p dir="ltr">Moving the identical hook to user settings on the same machine makes it arrive. Running the identical managed hook from the terminal CLI on the same machine makes it arrive. The same managed configuration delivers normally in the desktop app on macOS. Only the combination of managed settings, the desktop app and Windows fails.</p><div dir="ltr"><div>
Settings source | Surface | additionalContext delivered
-- | -- | --
managed | Windows, desktop app | no
managed | Windows, terminal CLI | yes
user | Windows, desktop app | yes
managed | macOS, desktop app | yes
</div></div><!--EndFragment-->
</body>
</html>
What Should Happen?
The model receives the additionalContext string from a managed SessionStart hook, as it does from the same hook declared in user settings and as it does on macOS.
Error Messages/Logs
None — that is the substance of the report. Exit code 0, valid JSON on stdout, the hook logged as having run successfully, and no error anywhere. The text is dropped silently.
Steps to Reproduce
Create C:\Users\Public\probe.ps1 with exactly these two lines. The first prints the hook payload; the second leaves proof that the hook ran.
'{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"MARKER-ALPHA-9731"}}'
New-Item -ItemType File -Force -Path "$env:USERPROFILE\.probe-ran" | Out-Null
Confirm the script emits valid JSON on its own:
'{"source":"startup"}' | & powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Users\Public\probe.ps1"
Register it in C:\Program Files\ClaudeCode\managed-settings.json:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"C:\\Users\\Public\\probe.ps1\""
}
]
}
]
}
}
Remove-Item "$env:USERPROFILE\.probe-ran" -ErrorAction SilentlyContinue
Start a session in the desktop app and ask the model: "Find the string MARKER-ALPHA-9731 in your context and quote it. If it is not there, say so." The model reports it is not there.
Test-Path "$env:USERPROFILE\.probe-ran" returns True — the hook ran during that session.
Move the same hooks block from managed-settings.json to %USERPROFILE%\.claude\settings.json, change nothing else, repeat steps 4–5. The model quotes the marker.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.292
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
Ruled out by measurement, not reasoning:
Not the hook failing to run — the side-effect file is absent before the session and present after, checked in that order.
Not malformed output — step 2 prints one line of valid JSON of the documented shape.
Not the invocation form — tried both "command": "powershell.exe" with an args array and a single "command" string holding the whole command line. Both fail from managed settings. The args form demonstrably works for PreToolUse hooks in the same managed file, which decide and report normally, so managed hooks are read and executed; only this event's output is dropped.
Not a size limit — payload under 1 KB against a known threshold around 10 KB.
Not interference between hooks — reproduced with a single hook registered.
Why this matters beyond a missing message: for a managed deployment the SessionStart hook is how an organization's policy introduces itself and states any step it requires at session start. Ours asks the agent to review the standing permissions the user has granted. On the affected surface that review never happens and nothing indicates it was skipped. The asymmetry hides it: an administrator verifying the policy from a terminal sees it working, while desktop users get nothing.
Related, none of them this: anthropics/claude-code#93458 reports Windows desktop with startup delivering and only fork dropping. anthropics/claude-code#16538 is the same symptom for plugin hooks with the same user-settings workaround, closed as not planned with no root cause recorded — plausibly one cause with this. anthropics/claude-code#88086 and anthropics/claude-code#76736 are the same symptom in the VS Code extension. anthropics/claude-code#13650 is the same symptom with neither surface nor settings source isolated.