crewAIInc / crewAIInc/crewAI

Auto-checkpoint raises PydanticSerializationError when a Task has a Python-callable guardrail

Open
#7,398 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
58.8k
Forks
8.5k
Avg merge
1d 15h
Merged PRs (30d)
109

Description

Summary

With auto-checkpointing enabled, CheckpointListener._do_checkpoint calls state.model_dump(mode="json"), which fails on any Task whose guardrail is a Python callable (a function/lambda, as opposed to a string guardrail). Pydantic can't JSON-serialize the callable, so:

  1. A UserWarning: Callable 'guardrail' cannot be JSON-serialized and will be dropped during checkpointing; restored checkpoints will not run this guardrail. fires, then
  2. model_dump(mode="json") still raises PydanticSerializationError: Unable to serialize unknown type: <class 'function'> (also seen as <class 'pydantic._internal._model_construction.ModelMetaclass'>), which is re-raised out of _do_checkpoint and logged by the event handler as a full WARNING:crewai.state.checkpoint_listener:Auto-checkpoint failed for event task_completed traceback.

Net effect: every checkpointed event on a guardrail-bearing task emits a traceback, and no usable checkpoint is written for that task.

Version

crewai 1.15.10 (also reproduces on 1.15.21). Python 3.12.

Actual behavior (real traceback)
UserWarning: Callable 'guardrail' cannot be JSON-serialized and will be dropped
during checkpointing; restored checkpoints will not run this guardrail.
WARNING:crewai.state.checkpoint_listener:Auto-checkpoint failed for event task_completed
Traceback (most recent call last):
  File ".../crewai/state/checkpoint_listener.py", line 242, in _on_any_event
    _do_checkpoint(state, cfg, event)
  File ".../crewai/state/checkpoint_listener.py", line 144, in _do_checkpoint
    payload = state.model_dump(mode="json")
pydantic_core._pydantic_core.PydanticSerializationError: Unable to serialize unknown type: <class 'function'>
Steps to reproduce

Configure a Crew with auto-checkpointing where on_events includes task_completed, and give one Task a callable guardrail (e.g. guardrail=my_fn where my_fn(output) -> (bool, Any)). Run kickoff(). Each task_completed triggers the failure above. String guardrails are unaffected.

Expected behavior

The checkpoint serializer should degrade gracefully on non-serializable fields (callable guardrails, and other non-JSON state) rather than raising: drop them from the snapshot with a single, quiet notice (not a per-event traceback), and still write the rest of the checkpoint. Callable guardrails are a first-class, documented feature, so checkpointing a task that uses one shouldn't fail or spam tracebacks.

Root cause

checkpoint_listener.py::_do_checkpoint -> state.model_dump(mode="json") has no default=/exclusion handling for callable/non-serializable fields; the except Exception at ~line 156 emits CheckpointFailedEvent and then raises, so the caller logs the whole traceback.

Workaround (downstream)

Restricting on_events to failure-only events (task_failed, crew_kickoff_failed) avoids the per-successful-task noise, but the underlying serialization gap remains for any checkpointed event on a guardrail-bearing task.

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.

Research direction

Start in checkpoint_listener.py, especially CheckpointListener._do_checkpoint and the _on_any_event path described in the traceback. Run the reported auto-checkpoint reproduction with a callable Task guardrail and verify that the remaining state is written without a per-event traceback, while the callable field is omitted with only one quiet notice.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.