[BUG] Session file not written before SIGTERM when response is short — --resume intermittently fails
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?
When using ClaudeSDKClient for sequential operations that resume sessions, short-lived operations intermittently fail with:
ProcessError: Command failed with exit code 1
The failure occurs on the second operation (the resume call) and appears non-deterministic, but strongly correlates with response length.
SubprocessCLITransport.close() sends SIGTERM immediately after closing stdin, without allowing the subprocess time to exit naturally. The CLI writes the session file after completing the response. For short responses, the session file has not yet been fully written when SIGTERM is delivered.
This results in an incomplete .jsonl session file that contains only queue-operation entries and no conversation messages. A subsequent --resume <session_id> call reads the malformed file and exits with code 1.
Longer responses (~16s+) consistently succeed, likely because the session file is written before the subprocess is terminated. This behavior suggests a race condition between session file flushing and forced process termination.
What Should Happen?
Resuming a session using --resume <session_id> should reliably succeed regardless of response length.
The subprocess should be allowed to exit naturally after stdin is closed, ensuring the session file is fully written and flushed before termination. Session files should never be left in a partially written or malformed state.
Sequential operations that resume sessions should behave deterministically, with no dependency on response duration or timing.
Error Messages/Logs
Steps to Reproduce
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
async def main():
options = ClaudeAgentOptions(permission_mode="bypassPermissions")
session_id = None
# Operation 1 — short response
async with ClaudeSDKClient(options=options) as client:
await client.query("List exactly 3 benefits of unit testing.")
async for msg in client.receive_response():
if hasattr(msg, "session_id"):
session_id = msg.session_id
print(f"Session ID: {session_id}")
# Operation 2 — immediate resume
resume_options = ClaudeAgentOptions(
permission_mode="bypassPermissions",
resume=session_id,
)
async with ClaudeSDKClient(options=resume_options) as client:
await client.query("Confirm completion.")
async for msg in client.receive_response():
print(msg)
for _ in range(5):
asyncio.run(main())
Run 5 times — done will fail intermittently with ProcessError: Command failed with exit code 1.
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.70
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗