<@ULVA73B9P> Why do flows show success even if the tasks within them timed out or failed?
j
@Marvin Why do flows show success even if the tasks within them timed out or failed?
m
thought for 107.1 seconds
In Prefect 3.x, a flow can show Success even when some tasks Failed or TimedOut because task state and flow state are separate. The short version: - Tasks get their own states - The flow gets its state based on how the flow function itself finishes - If the flow returns normally, Prefect will usually mark the flow Completed/Success, even if some tasks failed along the way Common reasons this happens: 1. The task failure was caught
Copy code
python
@flow
def my_flow():
    try:
        bad_task()
    except Exception:
        pass

    return "done"
The task failed, but the flow did not. Since the exception was handled, the flow completed successfully. 2. You submitted tasks asynchronously and never waited on them
Copy code
python
@flow
def my_flow():
    future = bad_task.submit()
    return "done"
Here the flow may finish before the task failure is surfaced to the flow. 3. You asked for task state/result explicitly but never used it to fail the flow
Copy code
python
@flow
def my_flow():
    state = bad_task(return_state=True)
    return "done"
The task state may be
Failed
, but the flow still returned normally. 4. A task timed out, but the flow didn’t propagate that failure A task timeout usually makes the task fail, but the flow only fails if that failure is raised/returned in a way the flow uses. How to make the flow fail when a task fails or times out Option A: let exceptions propagate
Copy code
python
@flow
def my_flow():
    bad_task()
If
bad_task()
raises and you don’t catch it, the flow fails. Option B: wait on submitted futures and call
.result()
Copy code
python
@flow
def my_flow():
    future = bad_task.submit()
    future.result()  # raises if task failed
That will surface the task failure to the flow. Option C: return failed states If you use
return_state=True
, inspect/return the state so Prefect can derive the flow state from it. A useful mental model is: - A failed task does not automatically imply a failed flow - A failed flow means the flow itself ended in an error/failed state If you want, I can also show: - a minimal reproducible example of this behavior - or a recommended pattern for making concurrent/submitted tasks fail the flow reliably Relevant docs: - States - Flows - Tasks