Please read this first
- Have you read the docs? Yes. This concerns the session backend
pop_item() behavior rather than a documented usage question.
- Have you searched for related issues? Yes. I searched upstream issues and PRs.
Describe the bug
pop_item() can return None after deleting a corrupted newest item even when older valid session history still exists. A caller can interpret None as an empty session and stop trimming or rewinding, while valid history remains in the backend.
The affected paths are the non-MongoDB session backends that remove the newest item before deserializing it, including SQLite, AsyncSQLite, Redis, SQLAlchemy, and Dapr. MongoDB already skips corrupted newest documents and continues to the next valid item after PR #3247.
Impact:
- Session state can be misreported as empty.
- A corrupted newest entry can hide older valid entries from callers using
pop_item().
- Recovery behavior differs across session backends for the same
SessionABC operation.
Debug information
- Agents SDK version: upstream
main at bc3607ba
- Python version: Python 3.12.1
Repro steps
Run this minimal script from a checkout with the repository development dependencies installed. It uses fakeredis so no external Redis server is required.
import asyncio
import fakeredis.aioredis
from agents.extensions.memory.redis_session import RedisSession
async def main() -> None:
client = fakeredis.aioredis.FakeRedis()
session = RedisSession("corrupt-pop", redis_client=client, key_prefix="test")
valid = {"role": "user", "content": "valid older item"}
await session.add_items([valid])
await client.rpush("test:corrupt-pop:messages", "not valid json {{{")
popped = await session.pop_item()
remaining = await session.get_items()
print(f"popped: {popped!r}")
print(f"remaining: {remaining!r}")
asyncio.run(main())
Actual result on upstream main at bc3607ba:
popped: None
remaining: [{'role': 'user', 'content': 'valid older item'}]
Expected behavior
pop_item() should discard corrupted newest items and continue looking for the next valid item. It should return None only when no valid item remains after corrupted entries are removed.
Please read this first
pop_item()behavior rather than a documented usage question.MongoDBSession.pop_item()and has been merged. This issue covers the remaining session backends, so it is adjacent but not a duplicate.Describe the bug
pop_item()can returnNoneafter deleting a corrupted newest item even when older valid session history still exists. A caller can interpretNoneas an empty session and stop trimming or rewinding, while valid history remains in the backend.The affected paths are the non-MongoDB session backends that remove the newest item before deserializing it, including SQLite, AsyncSQLite, Redis, SQLAlchemy, and Dapr. MongoDB already skips corrupted newest documents and continues to the next valid item after PR #3247.
Impact:
pop_item().SessionABCoperation.Debug information
mainatbc3607baRepro steps
Run this minimal script from a checkout with the repository development dependencies installed. It uses
fakeredisso no external Redis server is required.Actual result on upstream
mainatbc3607ba:Expected behavior
pop_item()should discard corrupted newest items and continue looking for the next valid item. It should returnNoneonly when no valid item remains after corrupted entries are removed.