From b18054371c6ce08c6bc322a7b0de41b67fc60408 Mon Sep 17 00:00:00 2001 From: you-n-g Date: Sat, 8 Nov 2025 22:55:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20avoid=20triggering=20errors=20like=20"Ru?= =?UTF-8?q?ntimeError:=20dictionary=20changed=20s=E2=80=A6=20(#1285)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: avoid triggering errors like "RuntimeError: dictionary changed size during iteration" * style: reformat run_in_executor call for improved readability --- rdagent/utils/workflow/loop.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rdagent/utils/workflow/loop.py b/rdagent/utils/workflow/loop.py index 9fdaa529..34dc119e 100644 --- a/rdagent/utils/workflow/loop.py +++ b/rdagent/utils/workflow/loop.py @@ -10,6 +10,7 @@ Postscripts: import asyncio import concurrent.futures +import copy import os import pickle from collections import defaultdict @@ -227,7 +228,11 @@ class LoopBase: if force_subproc: curr_loop = asyncio.get_running_loop() with concurrent.futures.ProcessPoolExecutor() as pool: - result = await curr_loop.run_in_executor(pool, func, self.loop_prev_out[li]) + # Using deepcopy is to avoid triggering errors like "RuntimeError: dictionary changed size during iteration" + # GUESS: Some content in self.loop_prev_out[li] may be in the middle of being changed. + result = await curr_loop.run_in_executor( + pool, copy.deepcopy(func), copy.deepcopy(self.loop_prev_out[li]) + ) else: # auto determine whether to run async or sync if asyncio.iscoroutinefunction(func):