SessionStart: plugin hook's `hookSpecificOutput` format silently drops concurrent user hook's flat `additionalContext`
Bug Report
Preflight checklist
- [x] I've searched existing issues and this hasn't been reported (related: #28372, which covers a parallel race condition in the same merging layer)
- [x] This is a single bug
Description
When a plugin-registered SessionStart hook outputs the hookSpecificOutput nested format and a user-registered hook outputs the flat additionalContext format, only the plugin's context reaches Claude — the user hook's context is silently dropped.
The docs state: "Multiple hooks' values are concatenated" (hooks.md, SessionStart additionalContext field). That's not what happens here.
Steps to Reproduce
- Enable a plugin that registers a SessionStart hook outputting:
``json`
{"hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": "plugin content"}}
explanatory-output-style@claude-plugins-official`)
(e.g.
- Register a user SessionStart hook in
settings.jsonthat outputs:
``json``
{"additionalContext": "user content"}
- Start a new session.
Expected: Claude receives both "plugin content" and "user content" concatenated.
Actual: Claude only receives "plugin content". The user hook's output is silently dropped.
Additional context
- The user hook runs successfully (exit 0) and produces valid JSON — verified by running it manually.
- Swapping the format of the user hook to use
hookSpecificOutputdoesn't change the outcome. - The
SessionStart:startup hook success: Successmessage appears in Claude's context, confirming the hook fired — but theadditionalContextvalue never arrives. - Workaround: Consolidate both hooks into a single user hook and disable the plugin.
Environment
- Claude Code version: current as of 2026-03-06
- macOS (darwin 25.3.0, Apple Silicon)
- Plugin:
explanatory-output-style@claude-plugins-official
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗