Nate
05/14/2026, 4:53 PMexplain raise_on_failure behaviour pls. Particularly, I want to clarify if this can be called directly to the task call (using just task_name(raise_on_failure=False) ), or only for task_name.submit().result(raise_on_failure=False)? What is the default value and what are typical cases in Prefect v3? I want to make the task fail (red in UI) but proceed with the next task. When I just raise the exception in my task, the whole flow fails(i'll look into what happened)
Marvin
05/14/2026, 4:53 PMMarvin
05/14/2026, 4:55 PMraise_on_failure lives.
Short answer
- task_name(raise_on_failure=False) β no, that is not how Prefect v3 task calls work
- task_name.submit(...).result(raise_on_failure=False) β yes
- state.result(raise_on_failure=False) β yes
- Default is raise_on_failure=True
So if you call a task normally and it raises, Prefect will usually propagate that exception into the flow, which causes the flow to fail too.
To make a task show as failed in the UI but allow the flow to continue, the usual pattern is:
python
state = task_name(..., return_state=True)
if state.is_failed():
err = state.result(raise_on_failure=False)
# log / branch / ignore / handle
That task run will still be red in the UI, but since you captured the State instead of letting the exception bubble, the flow can keep going.
Example
python
from prefect import flow, task
@task
def step_1():
raise ValueError("boom")
@task
def step_2():
print("still running")
@flow
def my_flow():
state = step_1(return_state=True)
if state.is_failed():
err = state.result(raise_on_failure=False)
print(f"step_1 failed: {err}")
step_2()
my_flow()
What happens here:
- step_1 is marked Failed in Prefect
- step_2 still runs
- the flow can still complete successfully unless you re-raise or otherwise fail it yourself
Why your flow currently fails
When you do this:
python
result = step_1()
and step_1 raises, Prefect resolves the task result with the default behavior of raise_on_failure=True, so the exception is re-raised into the flow.
Typical cases for raise_on_failure=False
Usually used when you want to:
- inspect a failed task without crashing the flow
- implement best-effort / optional tasks
- branch on success vs failure
- collect partial results from many submitted tasks
Examples:
python
future = my_task.submit()
value_or_exc = future.result(raise_on_failure=False)
or
python
state = my_task(return_state=True)
value_or_exc = state.result(raise_on_failure=False)
Important nuance
If you want the task to fail and downstream tasks to continue, you usually need state-based control flow, not ordinary Python result passing.
Because this will still blow up:
python
x = my_task() # failing task -> exception raised into flow
next_task()
Whereas this will not:
python
state = my_task(return_state=True)
next_task()
Rule of thumb
- Want the actual result and fail fast? β my_task()
- Want to inspect success/failure yourself? β my_task(return_state=True)
- Want concurrent execution? β future = my_task.submit(), then future.result(...)
Relevant docs/source-backed behavior:
- Prefect tasks
- Prefect flows
- Prefect state reference
If you want, I can also show:
1. the same pattern for .submit() futures, or
2. how to structure a flow so the flow ends in a custom state like βcompleted with some task failures.β