[BUG] Cross-session message delivered to a stream-json session emits no user frame on stdout — SDK hosts render a reply with no prompt
A cross-session message reaches the model and lands in the transcript, but the CLI emits no {"type":"user"} frame on stdout, so Agent SDK hosts render an assistant reply with no prompt above it. The ask: emit that frame with origin.kind === 'peer'.
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?
Agent SDK hosts drive the CLI with --output-format stream-json --input-format stream-json --verbose, where nothing on stdout says a prompt arrived. I saw it in T3 Code desktop 0.0.38, then reproduced it against the CLI with no host. The one partial signal is system/init, re-emitted at the start of the injected turn: no content, no sender.
What Should Happen?
Emit a user frame when a message is injected from outside the host's stdin. SDKUserMessage (sdk.d.ts:4583) carries origin?: SDKMessageOrigin (sdk.d.ts:4593), whose peer variant (sdk.d.ts:4030) already carries the sender and the decoded body, documented as "byte-exact with what the model sees ... render this instead of re-parsing the message text". The contract is in the types; the frame just isn't sent.
Steps to Reproduce
- Start a headless stream-json session, keeping stdin open:
````
{ echo '{"type":"user","message":{"role":"user","content":"say ok"}}'; sleep 300; } \
| claude --output-format stream-json --input-format stream-json --verbose \
> out.ndjson
(fifo originally; sleep is equivalent; untested with -p)
- Read
messaging_socket_pathoff thesystem/initframe inout.ndjson. - From a second session,
SendMessageto that address with a unique marker. - Watch
out.ndjson: the marker returns in anassistantframe, nouserframe.
Error Messages/Logs
$ grep -o '"type":"[a-z_]*"' out.ndjson | sort | uniq -c
3 "type":"assistant"
2 "type":"command_lifecycle"
5 "type":"message"
2 "type":"rate_limit_event"
2 "type":"result"
13 "type":"system"
2 "type":"text"
1 "type":"thinking"
$ grep -c '"type":"user"' out.ndjson
0
message, text and thinking there are nested content-block fields, not frames.
Delivered, from the transcript jsonl, marker redacted:
{"parentUuid":"b3c4aa51-...","isSidechain":false,"promptId":"b83b431b-...","type":"user","message":{"role":"user","content":"Another Claude session sent a message:\n<cross-session-message from=\"uds:/tmp/cc-socks/72606.sock\" from-name=\"code-a8\" from-mode=\"bypass\">\n<agent-message from=\"...\">\n<marker> ...
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Claude Code Version
2.1.259
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Non-interactive/CI environment
Additional Information
No Agent SDK host can show cross-session traffic; the only way to see what was asked is the transcript jsonl. Peer messages only. macOS 26.6.2 (arm64), permissionMode: bypassPermissions; citations against @anthropic-ai/claude-agent-sdk 0.3.220.
Related, and distinct:
- #79311 — MCP
claude/channelnotifications missing from the VS Code panel; a host bug. Here it's the CLI's own stdout. - #87323 — the inverse: in the transcript, never reaching the model. Here the model gets it, the host doesn't.
- #86059 — same inverse, context the model never sees.
- #91362 — a TUI preview regression; not the stream-json frame set.
Drafted with Claude Code (Claude Opus 5) from source and transcripts on my machine; I reviewed and posted it.