[DOCS] Logic flaw in Python File Checkpointing example creates potential race condition
Documentation Type
Unclear/confusing documentation
Documentation Location
https://platform.claude.com/docs/en/agent-sdk/file-checkpointing
Section/Topic
The "Implement checkpointing" section, specifically the Python code example tab within step 3.
Current Documentation
The current Python example suggests the following pattern for rewinding files:
# Step 3: Later, rewind by resuming the session with an empty prompt
if checkpoint_id and session_id:
async with ClaudeSDKClient(ClaudeAgentOptions(
enable_file_checkpointing=True,
resume=session_id
)) as client:
await client.query("") # Empty prompt to open the connection
async for message in client.receive_response():
await client.rewind_files(checkpoint_id)
break
print(f"Rewound to checkpoint: {checkpoint_id}")
What's Wrong or Missing?
The logic presented is flawed and non-deterministic. It sends an empty prompt (await client.query("")) to "open the connection," but places the critical await client.rewind_files(checkpoint_id) call inside the async for loop that consumes the response to that empty prompt.
- Dependency on Model Output: If the model does not generate a response event to an empty string (or if the stream closes immediately without yielding the specific message type required to enter the loop), the code inside the loop will never execute. Consequently, the files will never be rewound.
- Race Condition: Sending a control signal (
rewind_files) while simultaneously consuming the response stream creates a race condition on the message stream state.
Suggested Improvement
The example should be updated to a robust pattern that does not rely on the model generating tokens for an empty prompt to trigger a control signal.
If the SDK requires an active connection to send the rewind command, the documentation should clarify if rewind_files can be awaited before or outside the message consumption loop, or provide a prompt that guarantees a response event (e.g., specific to keeping the session alive) to ensure the loop is entered.
Ideally, the pattern should look closer to this (pseudocode, pending SDK capability verification):
if checkpoint_id and session_id:
async with ClaudeSDKClient(ClaudeAgentOptions(
enable_file_checkpointing=True,
resume=session_id
)) as client:
# Connect without sending a prompt if possible, or send prompt and rewind immediately
await client.connect()
await client.rewind_files(checkpoint_id)
If the loop is strictly required by the SDK's internal architecture, the comment should explain why the loop is necessary for the signal to process.
Impact
High - Prevents users from using a feature
Additional Context
- This issue appears specifically in the Python tab of the "Implement checkpointing" section.
- Similar logic appears in the "Try it out" section (
try_checkpointing.py) on the same page.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗