Skip to content

fix(flow): explain the route-label/method-name collision in the self-listen error (#6767) - #6777

Open
Anai-Guo wants to merge 1 commit into
crewAIInc:mainfrom
Anai-Guo:fix/flow-self-listen-route-collision-message
Open

fix(flow): explain the route-label/method-name collision in the self-listen error (#6767)#6777
Anai-Guo wants to merge 1 commit into
crewAIInc:mainfrom
Anai-Guo:fix/flow-self-listen-route-collision-message

Conversation

@Anai-Guo

@Anai-Guo Anai-Guo commented Aug 2, 2026

Copy link
Copy Markdown

Fixes #6767.

What's going on

In a conversational Flow, the string passed to @listen("...") is a router route label. FlowDefinition._validate_trigger_namespace also uses that field for method-to-method triggers, so naming a handler after the route it serves — the naming everyone reaches for first — fails at instantiation with:

Value error, methods.create_video.listen must not reference itself

which sends you looking for a self-referential trigger you never wrote.

Why the guard has to stay

The issue offered two options; I went with the second (explain the collision) because separating the namespaces would reintroduce the infinite loop the guard exists to prevent.

Route labels and method names are genuinely one trigger namespace at runtime. After a listener runs, _execute_single_listener calls _execute_listeners(listener_name, ...) (flow/runtime/__init__.py), so a method that listens for its own name re-triggers itself on every completion. The engine already knows this — the max_method_calls RecursionError says "This commonly happens when a @listen label matches the method's own name." Allowing @listen("create_video") on def create_video would just trade an instantiation-time error for a runtime loop that burns max_method_calls LLM turns first.

The change

Keep rejecting it, but say why, and tailor the explanation to the flow kind:

Conversational flow (new):

methods.create_video.listen must not reference itself. In a conversational flow
'create_video' is both a router route label and a method name, and the two share
one trigger namespace, so the method would re-trigger itself once it finishes.
Rename the handler and keep @listen("create_video") as the route label.

Regular flow (new):

methods.step.listen must not reference itself. A method's completion is itself a
trigger, so listening for its own name would re-trigger it forever. Listen for
the method that should precede it.

Validation behaviour is unchanged — same flows are accepted and rejected, only the message text is new.

Verification

Reproduced the issue's snippet verbatim against crewai 1.15.9, whose flow_definition.py, conversational_definition.py and flow/dsl/_utils.py are byte-identical to main, then re-ran it with the patch applied.

  • Two regression tests added to lib/crewai/tests/test_flow_definition.py (one per branch). Both fail on main and pass with the fix.
  • Full test_flow_definition.py: 61 passed.
  • ruff==0.15.1 format --config pyproject.toml: already formatted. ruff check reports one pre-existing I001 on this file that is present on main unchanged, so I left the import block alone rather than churning it into the diff.

🤖 Generated with Claude Code

…listen error (crewAIInc#6767)

`FlowDefinition._validate_trigger_namespace` rejects a method whose @listen
condition names the method itself. In a conversational flow the string passed
to @listen is a router route label, so naming the handler after the route it
serves -- the most natural naming there is -- trips the guard and surfaces as
"methods.create_video.listen must not reference itself", which reads as if the
developer wrote a self-referential method trigger they never wrote.

The guard itself is correct and has to stay: route labels and method names
share one trigger namespace, and the runtime re-triggers listeners on the
completing method's own name, so allowing the collision would make the handler
re-trigger itself until `max_method_calls` raises RecursionError (whose message
already blames "a @listen label matches the method's own name").

So keep rejecting it, but say why. The error now names the collision for
conversational flows and points at the fix (rename the handler, keep the
@listen label), and explains the re-trigger reasoning for regular flows.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 585ad27d-d63d-463d-b538-d2265221d556

📥 Commits

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

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

📝 Walkthrough

Walkthrough

The flow validator now adds contextual explanations to self-reference errors. Standard flows report repeated-trigger risk. Conversational flows identify route-label and method-name collisions. Tests cover both validation messages.

Changes

Self-reference validation

Layer / File(s) Summary
Contextual validation and coverage
lib/crewai/src/crewai/flow/flow_definition.py, lib/crewai/tests/test_flow_definition.py
The validator uses _self_reference_hint to generate different messages for standard and conversational flows. Tests verify repeated-trigger guidance and route-label collision guidance.

Suggested reviewers: vinibrsl

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: explaining route-label and method-name collisions in self-listen validation.
Description check ✅ Passed The description directly explains the validation-message change, its rationale, implementation, and regression tests.
Linked Issues check ✅ Passed The PR satisfies issue [#6767] by retaining the guard and clearly explaining the conversational route-label and method-name collision.
Out of Scope Changes check ✅ Passed The changes are limited to the requested validation-message update and regression tests for regular and conversational flows.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Conversational Flow golden use case improvements - route labels collide with method names in @listen validation

1 participant