#23137·prefect

Flow ends COMPLETED when it returns a list of .map() results containing a FAILED task (states nested one level are ignored)

Author: mgsnunoCreated Sep 17, 2026Updated Sep 17, 2026
Labelsbug

Bug summary

A flow that returns a list containing the results of two or more .map() calls ends COMPLETED even when one of the mapped tasks FAILED. The same flow returning a flat list of the same futures ends FAILED('1/2 states failed.').

python
from prefect import flow, task

@task
def boom(x):
    raise ValueError(f"boom {x}")

@task
def fine(x):
    return x

@flow
def nested():
    return [boom.map([1]), fine.map([2])]  # list of two PrefectFutureList

@flow
def flat():
    return [*boom.map([1]), *fine.map([2])]

print("nested final state:", nested(return_state=True).type)
print("flat   final state:", flat(return_state=True).type)
... Task run 'boom-c78' - Finished in state Failed('Task run encountered an exception ValueError: boom 1')
nested final state: StateType.COMPLETED
flat   final state: StateType.FAILED

Cause

return_value_to_state first resolves the futures (resolve_futures_to_states recurses through visit_collection, so the nested futures do become nested states), then calls is_state_iterable, which only checks all(isinstance(o, State) for o in obj) on the outer container. A list whose elements are lists of states fails that check, so the value is treated as plain data and the flow is COMPLETED. The docs ("Final state determination") say only that multiple states "must be contained in a set, list, or tuple", so nothing warns that one more level of nesting silently changes the outcome.

In our case this hid a mapped copy_table task that failed on every run for weeks: the flow runs were green, and the failed task run only showed when opening a run.

Suggested fix

Either recurse in is_state_iterable (or flatten nested set/list/tuple of states in return_value_to_state before the check), so that a nested container of states is aggregated like a flat one; or, if nesting is meant to be unsupported, fail or warn when the returned container still holds State objects after resolution instead of reporting COMPLETED.

Version info

Version:              3.8.6
Python version:       3.12.13
Server type:          ephemeral
Pydantic version:     2.13.5

Also reproduced on 3.8.4; is_state_iterable is unchanged on main as of 2026-09-17.