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.

Assessment

This issue has not been assessed yet.

Description

harness python reproduced

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:

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

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:

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.

Dominant language
Python
Stars
13.6k
Forks
2.3k
Avg merge
1d 21h
Merged PRs (30d)
362

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.

More from microsoft/agent-framework

All issues in microsoft/agent-framework

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.