Skip to content

Commit 60a7679

Browse files
committed
fix: fix sentinel bug in aprepare_kickoff, use _UNSET instead of None
The previous implementation used `None` as a sentinel to detect whether the before-callback loop had started. But a callback can legitimately return `None`, which would cause the next callback to receive the pre-callback inputs instead of the callback's return value. Introduces `_UNSET = object()` as a proper sentinel that no callback can accidentally produce, eliminating the double-run bug identified in the three-way comparison on crewAIInc#6482.
1 parent 3cfba59 commit 60a7679

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

lib/crewai/src/crewai/crews/utils.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,15 @@ def _extract_files_from_inputs(inputs: dict[str, Any]) -> dict[str, Any]:
247247
return files
248248

249249

250+
_UNSET: Any = object()
251+
"""Sentinel for detecting whether before-callback iteration has started.
252+
253+
Using ``None`` as a sentinel is unsafe because a before-callback can
254+
legitimately return ``None`` — the next callback would then receive the
255+
pre-callback inputs instead of the callback's return value.
256+
"""
257+
258+
250259
def _run_before_callbacks(
251260
crew: Crew,
252261
normalized: dict[str, Any] | None,
@@ -429,16 +438,16 @@ async def aprepare_kickoff(
429438
The potentially modified inputs dictionary after before callbacks.
430439
"""
431440
normalized = _normalize_inputs(crew, inputs)
432-
# Run callbacks in async mode so awaitable results are resolved.
433-
result: dict[str, Any] | None = None
441+
result: dict[str, Any] | None = _UNSET
434442
for before_callback in crew.before_kickoff_callbacks:
435-
if result is None:
443+
if result is _UNSET:
436444
result = normalized if normalized is not None else {}
437445
result = before_callback(result)
438446
if inspect.isawaitable(result):
439447
result = await result
440-
normalized = result
441-
return _prepare_kickoff_common(crew, normalized, input_files)
448+
if result is _UNSET:
449+
result = normalized
450+
return _prepare_kickoff_common(crew, result, input_files)
442451

443452

444453
class StreamingContext:

0 commit comments

Comments
 (0)