Messages sent to stdin during active turn are not persisted to conversation history

Resolved 💬 3 comments Opened Mar 31, 2026 by keithschacht Closed May 4, 2026

Description

When using --input-format=stream-json --output-format=stream-json, messages sent to stdin while Claude is mid-turn (e.g., during tool execution) are processed in-memory but not persisted to the conversation history JSONL file. When the session ends and is resumed with --resume, those messages are completely lost.

Messages sent while Claude is idle (between turns) ARE correctly persisted and survive --resume.

Reproduction

  1. Start Claude with stream-json:

``
claude -p --input-format=stream-json --output-format=stream-json --resume <session_id>
``

  1. Send a message that triggers a long-running tool call (e.g., a Bash command that takes 30 seconds)
  1. While the tool is executing, send a second message to stdin:

``json
{"type":"user","message":{"role":"user","content":"The secret passphrase is: Mary had a little lamb. When you reply, tell me the last word of this passphrase."}}
``

  1. Wait for the tool to finish. Claude processes the interjected message and responds correctly — it knows the passphrase and can tell you the last word is "lamb." ✅
  1. While still in the same session (before it exits), ask Claude the last two words of the passphrase. It remembers it. ✅
  1. Exit the session and resume:

``
claude -p --input-format=stream-json --output-format=stream-json --resume <session_id>
``

  1. Ask Claude for the last three words of the passphrase. It has no knowledge of it. ❌ It apologizes for hallucinating, it has no idea what it previously said "lamb" and "a lamb".
  1. Inspect the session JSONL file — the mid-turn message is not present. Messages sent between turns (while idle) are present.

Expected Behavior

All messages sent to stdin should be persisted to the conversation history regardless of whether they arrive during an active turn or between turns. If Claude processes a message in-memory, it should also be saved to the JSONL history file.

Actual Behavior

  • Messages sent between turns → persisted ✅
  • Messages sent during tool execution → processed in-memory but NOT persisted ❌
  • Messages sent during thinking/response generation → processed in-memory but NOT persisted ❌

Impact

This is a significant issue for applications that use Claude Code as a backend service where multiple message sources need to inject context during active processing. The workaround of "only send messages between turns" defeats the purpose of the streaming stdin protocol, which is designed to accept messages at any time.

Environment

  • Claude Code CLI (latest)
  • macOS
  • Using --input-format=stream-json --output-format=stream-json

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗