AgentFixboard

Automatic checkpoint during an async listener write fails with PanicException

A flow with checkpoint=CheckpointConfig(on_events=["method_execution_finished"]) and concurrent async listeners fails with pyo3_runtime.PanicException: dictionary changed size during iteration.

From GitHub

crewAIInc/crewAI

Difficulty
Easy
Time
~5 min
Steps
2
Fixed in
—
Last checked

Not fixed upstream yet: the issue is open. Source: issue open. Last checked 2026-10-23.

Symptom

A flow with checkpoint=CheckpointConfig(on_events=["method_execution_finished"]) and concurrent async listeners fails with pyo3_runtime.PanicException: dictionary changed size during iteration.

Evidence what you'll see

  • The traceback ends in crewai/state/checkpoint_listener.py at _do_checkpoint, on payload = state.model_dump(mode="json"), and reaches kickoff through kickoff_async.
  • On Ubuntu 22.04 the report's snippet failed on the first or second attempt in every run, on 1.15.28 and on main fa6d712. On macOS the timing rarely lined up.
  • The checkpointing guide says a failed automatic write is logged and the run continues. Here the write takes the whole run down.

Why it happens

The checkpoint handler serializes the live runtime state on an event-bus worker thread while another listener adds keys on the event loop. Pydantic-core's PanicException subclasses BaseException, so it escapes both except Exception clauses in _on_any_event and is_call_handler_safe. kickoff_async then re-raises it from _event_futures.

Affected versions

crewAI 1.15.28 and main fa6d712, Ubuntu 22.04, async listeners on one event loop writing disjoint keys. The listeners themselves are not multi-threaded; the concurrent reader is CrewAI's checkpoint handler.

Fix steps

0 of 2 done

Your check marks stay in this browser only.

How to check it worked

  • The report's ScanFlow snippet completes without pyo3_runtime.PanicException: dictionary changed size during iteration.

If it still fails

  • Issue #6327 removed StateProxy and is about unsynchronized shared-state mutation across threads. This report's listeners run on one thread and write disjoint keys.
  • The linked issue does not name a release that snapshots state before the handler thread serializes it.

Sources and credit

Summarized in our own words from these public reports. Credit goes to their authors.

Provided as is, without warranty. Try changes in a non-production environment and back up first. Security-related steps: verify against the official docs. Terms · Request removal or attribution change

Hit an error we don't cover? Submit it