What is or_()?
or_(a, b, ...) is the non-deterministic-friendly sibling of and_(): the downstream @listen(or_(...)) handler runs as soon as whichever upstream branch finishes first, without waiting for the others. That matches business processes where multiple strategies race — for example, a fast cache lookup versus a slow LLM expansion — and you want whichever returns first to unblock the pipeline.
Router-heavy flows often converge divergent tags into a single cleanup or notification step. Wrap those router targets inside or_() so the shared listener executes once the winning branch completes. Be explicit in code comments about what happens to losing branches: their side effects may still be mid-flight unless you cancel them yourself, because or_() only controls listener scheduling, not upstream task cancellation.
Testing or_() paths requires covering every upstream individually; branch coverage tools will flag missing cases if you only exercise the happy path. Log which upstream fired by capturing return values or state flags inside each branch so observability can prove the disjunction resolved the way you expected.
Use Cases
- • Router convergence
- • Either-branch handlers
Key Features
- ✓ OR semantics
- ✓ Variadic
When NOT to Use
When you need both inputs — use and_().
Notes
Do not confuse with boolean OR in Python
or_() is a flow combinator object consumed by @listen, not a shortcut for Python logical OR on return values.
Winner-only semantics
Downstream code should tolerate whichever branch populated state. Guard against KeyError when a branch skipped setting a field.
Pair with plot()
Complex or_ graphs are hard to read in source. Regenerate Flow.plot artifacts whenever you change combinator wiring.
When you actually need and_
If downstream must merge outputs from every branch, switch to and_() or split into two listeners to avoid subtle partial-data bugs.
Code Examples
Either
@listen(or_(approved, rejected))
def notify(self):
send_email()
Race with fallback
@listen(or_(fast_cache, slow_llm))
def merge(self):
if self.state.cache_hit:
return self.state.cache_hit
return self.state.llm_answer
When to Use
Either-or paths converging on a common step.
Common Mistakes
❌ Expecting all branches to fire
✅ Use and_() if you need all.
Related: @tool decorator reference, Agent class reference, and the first Crew tutorial.
or_() FAQ
What is or_() in CrewAI?
Combinator that makes @listen fire on the FIRST of the listed upstream methods. or_(a, b, ...) is the non-deterministic-friendly sibling of and_(): the downstream @listen(or_(...)) handler runs as soon as whichever upstream branch finishes first, without waiting for the others. That matches business processes where multiple strategies race — for example, a fast cache lookup versus a slow LLM expansion — and you want whichever returns first to unblock the pipeline. Router-heavy flows often converge divergent tags into a single cleanup or notification ste…
Which CrewAI types expose the method or_()?
DevShelfHub documents or_() on Flow. The reference maps it to Python module crewai.flow.flow — pin your installed crewai version and match imports to the snippet on this page.
When should I use or_()?
Either-or paths converging on a common step.
When should I avoid or_()?
When you need both inputs — use and_().
How do I call or_() from Python?
@listen(or_(step_a, step_b))
Where can I explore more CrewAI API reference pages?
Open the CrewAI API reference index on DevShelfHub to search classes, methods, and decorators, each with runnable examples, parameters, common mistakes, and cross-links.