Windows desktop app: plugin SessionStart hook executes but its stdout is never injected into session context
Summary
In the Windows desktop app, a plugin-provided SessionStart hook demonstrably executes (verified via a side-effect marker log), CLAUDE_PLUGIN_ROOT is set correctly, and the hook's cat succeeds — but the hook's stdout never reaches the session context. The model reports having no injected context. The same plugin's skills load and work fine in the same session, and manually invoking the context-loading skill works.
Per the hooks docs, SessionStart stdout (exit 0) should be added to session context, and the desktop docs list hooks as supported (not on the "not available in Desktop" list).
Environment
- Windows 11 Home 10.0.26200
- Claude Code desktop app (auto-updated, latest as of 2026-07-02)
- Plugin distributed via a private GitHub plugin marketplace; installed at user scope via the desktop Plugins UI; plugin version confirmed current in
installed_plugins.json
Hook (shell form)
hooks/hooks.json at plugin root:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|clear|compact",
"hooks": [
{
"type": "command",
"command": "echo \"hook-fired $(date '+%F %T') root=[${CLAUDE_PLUGIN_ROOT:-UNSET}]\" >> \"$HOME/.claude/strixx-hook.log\" 2>/dev/null; cat \"${CLAUDE_PLUGIN_ROOT:-$HOME/.claude/plugins/marketplaces/strixx-marketplace/plugins/strixx-skills}/skills/strixx-context/SKILL.md\""
}
]
}
]
}
}
Evidence the hook ran but output was discarded
Marker log written by the hook itself, timestamps matching new desktop sessions:
hook-fired 2026-07-02 13:33:31 root=[C:/Users/Leiko/.claude/plugins/cache/strixx-marketplace/strixx-skills/0.4.2]
hook-fired 2026-07-02 13:34:32 root=[C:/Users/Leiko/.claude/plugins/cache/strixx-marketplace/strixx-skills/0.4.2]
- The
root=[...]path is valid; the target file exists there (6,886 bytes) — socatoutput ~7 KB to stdout with exit 0. - In those exact sessions, asking Claude "without reading any files: do you have <the injected context>?" → it answers no, and confirms only CLAUDE.md files are present in its context.
- Same session: the plugin's skills are listed and invocable — plugin itself is loaded; only the hook's stdout is lost.
- Running the identical command in a terminal prints the file correctly.
Expected
Hook stdout (exit 0) appended to session context at SessionStart, as documented and as (reportedly) happens in the CLI.
Actual
Hook runs; stdout silently discarded; no error surfaced anywhere in the desktop UI.
Notes / related
- #16538 (macOS,
hookSpecificOutput.additionalContextvariant of plugin SessionStart output not surfacing) was closed as stale without resolution — this looks like the same underlying gap, reproduced on Windows desktop with the plain-stdout path. - #26192 (Windows SessionStart plugin hooks "hook error" despite succeeding) may be adjacent.
- Also hit along the way (docs/UX, not filing separately): exec-form (
command+args) is a trap for this use case on Windows — Git Bash binaries likecatdon't resolve against the system PATH, and${CLAUDE_PLUGIN_ROOT}is not expanded insideargs— combined with hook errors being invisible in the desktop app, this made diagnosis lengthy. Surfacing hook failures in the desktop UI would have saved most of it.
Workaround
CLAUDE.md instruction telling Claude to run the context-loading skill as its first action when the expected context is absent.