Skip to content

fix(flow): report the real CEL error for failures inside map literals - #6793

Merged
gabemilani merged 1 commit into
mainfrom
fix/cel-eval-error
Aug 3, 2026
Merged

fix(flow): report the real CEL error for failures inside map literals#6793
gabemilani merged 1 commit into
mainfrom
fix/cel-eval-error

Conversation

@gabemilani

@gabemilani gabemilani commented Aug 3, 2026

Copy link
Copy Markdown
Member

What

Flow CEL expressions that fail inside a map literal now report the actual error.
Before, a bad value in a map reported an internal serialization error:

${{'status': 1/0}}

→ failed to evaluate CEL expression: Object of type CELEvalError is not JSON serializable

Now it reports the cause, matching what the same expression reports on its own:

${{'status': 1/0}}

→ failed to evaluate CEL expression: ('modulus or divide by zero', ...)

This affects any failure nested in a map — division by zero, a missing state field, a bad conversion — which previously gave no indication of what was wrong.

Why

celpy raises evaluation errors that land at the top level of a result, but a map literal keeps the failed value in place and returns it. List literals propagate the error; maps don't. That returned error object reached json.dumps, which turned a clear CEL failure into an opaque serialization message.


Note

Low Risk
Localized change to CEL error handling in expressions.py with focused tests; no auth, persistence, or API surface changes.

Overview
Flow CEL evaluation now detects CELEvalError objects nested inside map (and list) results from celpy and re-raises them before JSON serialization, so failures like divide-by-zero or missing state fields surface as ExpressionError with the underlying cause instead of an opaque “not JSON serializable” message.

A recursive _find_cel_eval_error helper walks dict keys/values and list/tuple elements after program.evaluate(). Short-circuited failures (&&, ||, exists) that CEL never evaluates are unchanged and still succeed.

Tests add coverage for map/nested/list error shapes, message content for nested divide-by-zero, and guards that intentional short-circuiting still evaluates.

Reviewed by Cursor Bugbot for commit 167911f. Bugbot is set up for automated code reviews on this repo. Configure here.

@gabemilani
gabemilani requested a review from vinibrsl August 3, 2026 19:04
@gabemilani gabemilani self-assigned this Aug 3, 2026
@github-actions github-actions Bot added the size/S label Aug 3, 2026
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The CEL evaluator detects nested CELEvalError instances before serialization. Tests verify ExpressionError wrapping, divide-by-zero causes, and short-circuit behavior.

Changes

CEL error propagation

Layer / File(s) Summary
Nested CEL error detection
lib/crewai/src/crewai/flow/expressions.py
The evaluator recursively searches mappings and sequences for CELEvalError instances and raises the detected error before serialization.
Error propagation validation
lib/crewai/tests/test_flow_from_definition.py
Tests cover nested map and list errors, divide-by-zero causes, and errors suppressed by logical or collection short-circuiting.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: reporting underlying CEL errors from failures inside map literals.
Description check ✅ Passed The description directly explains the nested CEL error handling change and the tests added for error propagation and short-circuit behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cel-eval-error

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lib/crewai/src/crewai/flow/expressions.py (1)

24-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the recursive error scan.

_find_cel_eval_error recursively inspects dictionary keys and values, lists, and tuples. Add a docstring that states it returns the first nested CELEvalError.

As per coding guidelines, “Document public APIs and complex logic in Python code.”

Proposed documentation
 def _find_cel_eval_error(value: Any) -> Exception | None:
+    """Return the first CELEvalError found in nested CEL collections."""
     from celpy.evaluation import CELEvalError
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/flow/expressions.py` around lines 24 - 40, Add a
concise docstring to _find_cel_eval_error documenting that it recursively scans
dictionary keys and values, lists, and tuples, returning the first nested
CELEvalError found or None when absent.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/crewai/src/crewai/flow/expressions.py`:
- Around line 24-40: Add a concise docstring to _find_cel_eval_error documenting
that it recursively scans dictionary keys and values, lists, and tuples,
returning the first nested CELEvalError found or None when absent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 36b1b5ec-5cbd-4759-a308-008bf440db59

📥 Commits

Reviewing files that changed from the base of the PR and between c8f441c and fd58603.

📒 Files selected for processing (2)
  • lib/crewai/src/crewai/flow/expressions.py
  • lib/crewai/tests/test_flow_from_definition.py

@gabemilani
gabemilani enabled auto-merge (squash) August 3, 2026 19:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lib/crewai/src/crewai/flow/expressions.py (1)

24-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the recursive error search.

This helper contains non-obvious recursive logic. Add a docstring that defines the first-error behavior, the supported container traversal, and why the search runs before JSON serialization.

Suggested documentation
 def _find_cel_eval_error(value: Any) -> Exception | None:
+    """Find the first nested CELEvalError before JSON serialization.
+
+    Search mapping keys and values and list or tuple elements.
+    """

As per coding guidelines, document complex logic in Python code.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/flow/expressions.py` around lines 24 - 40, Add a
docstring to _find_cel_eval_error describing that it returns the first
CELEvalError found, recursively traverses dictionary keys and values plus list
and tuple elements, and must run before JSON serialization so nested evaluation
errors remain identifiable.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/crewai/src/crewai/flow/expressions.py`:
- Around line 24-40: Add a docstring to _find_cel_eval_error describing that it
returns the first CELEvalError found, recursively traverses dictionary keys and
values plus list and tuple elements, and must run before JSON serialization so
nested evaluation errors remain identifiable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c4e92070-9e41-4640-8708-a181a8382df2

📥 Commits

Reviewing files that changed from the base of the PR and between fd58603 and 167911f.

📒 Files selected for processing (2)
  • lib/crewai/src/crewai/flow/expressions.py
  • lib/crewai/tests/test_flow_from_definition.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/crewai/tests/test_flow_from_definition.py

@gabemilani
gabemilani merged commit 26518e0 into main Aug 3, 2026
57 of 123 checks passed
@gabemilani
gabemilani deleted the fix/cel-eval-error branch August 3, 2026 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants