fix: register checkpoint handlers when CheckpointConfig is created#5320
Conversation
iris-clawd
left a comment
There was a problem hiding this comment.
Review: Fix checkpoint handler registration
Good catch — classic chicken-and-egg bug. The fix is clean and minimal.
🟡 Side effect in model_validator
Registering global event bus handlers from a pydantic model_validator is a side effect that runs on every instantiation, including:
- Deserialization (
model_validate_json,model_validate) - Test fixtures that create
CheckpointConfigfor unit tests - Multiple
CheckpointConfiginstances in the same process
The _ensure_handlers_registered function is presumably idempotent (the name suggests it), so repeat calls should be fine. But worth confirming that the guard in _ensure_handlers_registered is threadsafe — if two Crews with checkpoint=True are created concurrently, you don't want double registration.
🟡 Circular import risk
The lazy import (from crewai.state.checkpoint_listener import _ensure_handlers_registered) inside the validator mitigates this, but checkpoint_config.py ← checkpoint_listener.py already has a dependency via _find_checkpoint importing CheckpointConfig. This creates a circular import path: checkpoint_config → checkpoint_listener → checkpoint_config. The lazy import in the validator should break the cycle at runtime, but it's fragile — a future top-level import in either file could trigger an ImportError.
✅ What looks good
- Minimal fix for a real bug (checkpoints silently never written)
- Lazy import avoids immediate circular dependency
model_validator(mode="after")is the right hook — config is fully populated
The circular import fragility is the main concern. If you wanted to be safer, you could register the handlers from the Crew/Flow init instead of the config validator. But for alpha, this works. 💬 167
iris-clawd
left a comment
There was a problem hiding this comment.
Approving — review notes are suggestions for later hardening. Good to land. ✅
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 50f1096. Configure here.
…com/crewAIInc/crewAI into fix/checkpoint-handler-registration
iris-clawd
left a comment
There was a problem hiding this comment.
Re-review after new commits
Scope expanded: now includes a _coerce_checkpoint BeforeValidator wired into Crew, Flow, and BaseAgent. Good improvement over the first version.
✅ What's better
_coerce_checkpointcentralizes theTrue → CheckpointConfig()coercion that was probably scattered or missing before. Clean pattern.- Handler registration now happens both in the BeforeValidator (for
checkpoint=Trueon Crew/Flow/Agent) and in the model_validator on CheckpointConfig itself (for direct instantiation). Belt and suspenders — good.
🟡 Double registration path
Both _coerce_checkpoint and CheckpointConfig._register_handlers call _ensure_handlers_registered(). When checkpoint=True is passed to a Crew:
_coerce_checkpointfires → createsCheckpointConfig()→ calls_ensure_handlers_registered()CheckpointConfig.__init__triggers_register_handlersmodel_validator → calls_ensure_handlers_registered()again
Harmless if idempotent, but redundant. Could drop the call from _coerce_checkpoint since the model_validator always covers it. Minor.
🟢 Import note
The _coerce_checkpoint function is imported at module level in crew.py, flow.py, and base_agent.py. Since it only does a lazy import of checkpoint_listener inside the function body (not at import time), this is safe. Good.
Looks solid. 💬 169
iris-clawd
left a comment
There was a problem hiding this comment.
Re-approving with updated commits. ✅

Summary
Checkpoint event handlers were never registered on the event bus during normal execution. The lazy registration in
_resolveonly ran from_find_checkpoint, which is called from the handler itself — a chicken-and-egg problem. Checkpoints were silently never written.Adds a
model_validatoronCheckpointConfigthat calls_ensure_handlers_registeredwhen any config is created, including fromcheckpoint=True.Test plan
Crew(checkpoint=True)writes checkpoints ontask_completedCrew(checkpoint=CheckpointConfig(...))writes checkpointscrewai checkpoint listshows written checkpointsNote
Medium Risk
Changes checkpoint initialization to eagerly register event-bus handlers when
checkpointis enabled, which affects runtime side effects during model validation forCrew/Flow/Agentconstruction.Overview
Fixes automatic checkpointing being silently inactive by ensuring checkpoint event handlers are registered as soon as checkpointing is configured.
Crew,Flow, andBaseAgentnow run aBeforeValidatoron thecheckpointfield that coercescheckpoint=Trueinto aCheckpointConfigand triggers handler registration.CheckpointConfigalso adds anaftermodel_validatorto register handlers whenever a config instance is created, preventing the previous chicken-and-egg lazy registration path.Reviewed by Cursor Bugbot for commit bee1506. Bugbot is set up for automated code reviews on this repo. Configure here.