Please read this first
- Read the RunState and Session documentation.
- Searched open issues and pull requests; no duplicate found.
Describe the bug
When a resumed RunState has input staged with RunState.add_input() and uses a client-managed Session, the SDK persists that guarded input before the next model call. If Session.add_items() commits the batch and then raises because the acknowledgement is lost, the RunState has no durable checkpoint for that append.
The input therefore remains pending. Retrying the same state runs the already-passing input guardrail again and appends the same logical input a second time. The behavior reproduces for sync and streaming runs, and after a RunState JSON round trip.
Debug information
- Agents SDK version: v0.22.0 and main at 89c02c8
- Python version: 3.13.9
- Operating system: macOS 15.6.1
- Model and model provider: deterministic local ScriptedModel; no provider request is needed
- Does the issue reproduce with the latest Agents SDK release? Yes
- Does the issue occur consistently or intermittently? Consistently
The raised exception is an intentional RuntimeError from a test Session immediately after it stores the supplied items, modeling a lost acknowledgement.
Repro steps
- Produce a resumable RunState and attach a client-managed Session.
- Call state.add_input("Late input").
- Make Session.add_items() store the batch and then raise.
- Retry Runner.run(agent, state, session=session), optionally after state.to_json() / RunState.from_json().
- Inspect Session history and input guardrail calls.
Observed result: the Session contains two occurrences of Late input and the same pending-input guardrail runs twice.
The same failure-before-commit case also lacks a resumable write checkpoint, so recovery cannot distinguish it from the lost-ack case.
Expected behavior
The pending input append should use the existing fail-closed Session write reconciliation mechanism. A retry should append once after an atomic failure, recognize an already committed lost-ack append without writing again, consume only the checkpoint-owned pending-input prefix, and not rerun a guardrail that already passed.
Please read this first
Describe the bug
When a resumed RunState has input staged with RunState.add_input() and uses a client-managed Session, the SDK persists that guarded input before the next model call. If Session.add_items() commits the batch and then raises because the acknowledgement is lost, the RunState has no durable checkpoint for that append.
The input therefore remains pending. Retrying the same state runs the already-passing input guardrail again and appends the same logical input a second time. The behavior reproduces for sync and streaming runs, and after a RunState JSON round trip.
Debug information
The raised exception is an intentional RuntimeError from a test Session immediately after it stores the supplied items, modeling a lost acknowledgement.
Repro steps
Observed result: the Session contains two occurrences of Late input and the same pending-input guardrail runs twice.
The same failure-before-commit case also lacks a resumable write checkpoint, so recovery cannot distinguish it from the lost-ack case.
Expected behavior
The pending input append should use the existing fail-closed Session write reconciliation mechanism. A retry should append once after an atomic failure, recognize an already committed lost-ack append without writing again, consume only the checkpoint-owned pending-input prefix, and not rerun a guardrail that already passed.