[BUG] Shared serializer turns Enum values into repr strings
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
Research direction
Start in crewai/utilities/serialization.py by reading to_serializable() and _to_serializable_key(), then inspect flow/runtime/_outputs.py and safe_serialize_to_dict() for their serializer usage. Run the offline reproduction from the issue and confirm that Enum, IntEnum, date-valued, tuple-valued, and dictionary-key cases preserve their declared values without repr strings or object ids.
Written by the indexing model from the issue text.
Description
Description
crewai.utilities.serialization.to_serializable() has no Enum branch, so any plain Enum value falls through to the repr() fallback. A string-valued enum such as Status.OK = "ok" is serialized as "<Status.OK: 'ok'>" instead of "ok".
This is not cosmetic. The shared serializer backs Flow expression outputs (flow/runtime/_outputs.py) and trace event conversion (safe_serialize_to_dict()), so an enum emitted by a flow method or included in trace data loses its declared wire value. IntEnum values currently pass through the int branch and keep their value only by accident of inheritance.
Enum values used as dictionary keys are also unstable: _to_serializable_key() produces a string containing the object id(), for example key_4383468448_<Key.X: 'x'>, which changes between runs.
This report was prepared with AI assistance. I cannot apply repository labels as an external contributor; please add the required
llm-generatedlabel.
Steps to reproduce
from enum import Enum
from crewai.utilities.serialization import to_serializable
class Status(Enum):
OK = "ok"
assert to_serializable({"status": Status.OK}) == {"status": "ok"}
# AssertionError: actual value is {"status": "<Status.OK: 'ok'>"}
Expected behavior
Enums should serialize to their declared .value consistently, for both values and dictionary keys. IntEnum, date-valued, and tuple-valued enums should recurse through the same value path so they keep their intended semantics.
Screenshots/Code snippets
The serializer handles primitives, UUIDs, dates, collections, dataclasses, and Pydantic models, then defaults everything else to repr(obj). Enum is missing between the primitive check and the fallback.
Operating System
macOS Sonoma
Python Version
3.13 (supported by the repository; not listed in the issue template)
crewAI Version
Current main (0374c631297f)
crewAI Tools Version
Current main (0374c631297f)
Virtual Environment
Venv (uv)
Evidence
A deterministic offline reproduction fails on current main and passes once Enum expands to to_serializable(obj.value) before the primitive check, with _to_serializable_key() doing the same for keys.
Possible Solution
Handle Enum first in to_serializable() by recursing into obj.value, and mirror that in _to_serializable_key().
Additional context
Closed, unmerged PR #5180 contained a similar enum-value fix inside a much broader tracing change; it was closed stale with maintainers inviting a focused follow-up. This issue scopes only the enum contract in the shared serializer.
- Dominant language
- Python
- Stars
- 58.8k
- Forks
- 8.5k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 103
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from crewAIInc/crewAI
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
-
[BUG] AttributeError: 'int' object has no attribute 'get' in crew_run_tui.py during plan rendering Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
[BUG] crewai-cli's runtime pin uv~=0.11.6 installs a second, capped uv into every consumer .venv Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
All issues in crewAIInc/crewAI
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100