RaceConditionError
concurrent.futures._base.RaceConditionError
Stack trace
concurrent.futures._base.RaceConditionError: Future object is done, cannot set result
File "asyncio/tasks.py", line 123, in _step
self._result = result
File "asyncio/futures.py", line 275, in set_result
raise RaceConditionError('Future object is done, cannot set result') Why it happens
Parallel AI tasks often share mutable state or resources without locks or synchronization primitives. When multiple tasks try to update the same future or shared variable simultaneously, a race condition arises, leading to inconsistent or corrupted state.
Detection
Monitor logs for RaceConditionError exceptions or inconsistent AI task outputs. Use debugging tools to detect concurrent access to shared variables or futures without proper locking.
Causes & fixes
Multiple async tasks attempt to set the result of the same Future object concurrently
Ensure each Future is set exactly once by coordinating task completion or using synchronization primitives like asyncio.Lock.
Shared mutable state accessed by parallel AI tasks without thread-safe mechanisms
Protect shared data with locks, queues, or use immutable data structures to avoid concurrent modification.
Improper use of concurrency libraries causing overlapping task completions
Review concurrency patterns and use high-level abstractions like asyncio.gather or concurrent.futures.ThreadPoolExecutor correctly.
Code: broken vs fixed
import asyncio
async def ai_task(future):
# Multiple tasks try to set the same future result concurrently
future.set_result('done') # This line causes RaceConditionError
async def main():
future = asyncio.Future()
await asyncio.gather(ai_task(future), ai_task(future))
asyncio.run(main()) import asyncio
async def ai_task(future, lock):
async with lock:
if not future.done():
future.set_result('done') # Fixed: synchronized access with lock
async def main():
future = asyncio.Future()
lock = asyncio.Lock() # Added lock to prevent race condition
await asyncio.gather(ai_task(future, lock), ai_task(future, lock))
if __name__ == '__main__':
asyncio.run(main())
print('Completed without race condition') Workaround
Wrap future.set_result calls in try/except blocks catching RaceConditionError and ignore duplicate sets, or redesign tasks to avoid shared futures.
Prevention
Design AI workflows to avoid shared mutable state or use concurrency-safe patterns like locks, queues, or immutable data. Prefer high-level concurrency APIs that manage synchronization internally.