microsoft / microsoft/agent-framework

Python: [Bug]: FileSystemAgentFileStore.delete can violate its result contract during concurrent deletion

Open
#8,456 1 comment 0 reactions 1 assignee View on GitHub

@westey-m is already working on this.

Since Sep 17, 2026.

harness python reproduced
Dominant language
Python
Stars
13.6k
Forks
2.3k
Avg merge
2d 45m
Merged PRs (30d)
358

Description

## Description

`AgentFileStore.delete()` documents `True` when deletion occurs and `False` when the file does not exist. `FileSystemAgentFileStore` currently performs its file check and deletion as separate operations. When two store instances share a root and delete the same path concurrently, both can pass the check and both report `True`, even though only one deletion occurs.

Against current `main` at `a3fc29dbd63a5223ece479b9b7eed53f50144999`, the exact reproduction below printed:

```text
attempt 2: [True, True]
```

For two concurrent same-path deletes within the same process, with no intervening write, one operation should return `True` and the other `False`. This does not request cross-process atomicity or delete/write transactional behavior.

I intend to submit a small fix that coordinates same-path deletion within the process, preserves the existing directory/non-file behavior, and maps only a `FileNotFoundError` deletion race to `False`.

## Code Sample

```python
import asyncio
from tempfile import TemporaryDirectory

from agent_framework import FileSystemAgentFileStore

async def main() -> None:
with TemporaryDirectory() as root:
first = FileSystemAgentFileStore(root)
second = FileSystemAgentFileStore(root)

for attempt in range(1, 1_001):
await first.write("shared.txt", "content")
try:
results = await asyncio.gather(
first.delete("shared.txt"),
second.delete("shared.txt"),
)
except FileNotFoundError as exc:
print(f"attempt {attempt}: {type(exc).__name__}: {exc}")
return

if sorted(results) != [False, True]:
print(f"attempt {attempt}: {results}")
return

print("no contract violation observed in 1000 attempts")

asyncio.run(main())
```

## Error Messages / Stack Traces

No exception was raised in the observed run. The exact output was:

```text
attempt 2: [True, True]
```

## Package Versions

`agent-framework-core`: source checkout of `main` at `a3fc29dbd63a5223ece479b9b7eed53f50144999` (workspace version `1.18.0`)

## Python Version

Python 3.12.12

## Additional Context

Observed on macOS/Darwin arm64. Issue #8255 and PR #8261 addressed analogous concurrent deletion behavior in `FileCheckpointStorage`; `FileSystemAgentFileStore` is a separate implementation and retains the race described here.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.