Dmytro Stelmakh
05/04/2026, 11:20 AMMarvin
05/04/2026, 11:20 AMMarvin
05/04/2026, 11:22 AMreturn_state=True.
That gives you the child flow’s State, and from there you can inspect whether it Completed or Failed and pull the data back with .result().
Example:
python
from prefect import flow
@flow
def child_flow(x):
if x < 0:
raise ValueError("x must be >= 0")
return {"value": x * 2}
@flow
def parent_flow(x):
child_state = child_flow(x, return_state=True)
if child_state.is_completed():
data = child_state.result()
print("Child returned:", data)
return data
if child_state.is_failed():
err = child_state.result(raise_on_failure=False)
print("Child failed with:", err)
return {"error": str(err)}
A few important details:
* child_flow(...) normally returns the child flow’s actual result
* child_flow(..., return_state=True) returns a State
* state.result() gets the returned value
* state.result(raise_on_failure=False) gets the exception object instead of re-raising it
So if you want to return data from either a Completed or Failed child run back to the main flow, return_state=True is the main pattern.
---
But your real issue sounds like serialization, not state access.
You mentioned the subflow is run in a container and receives:
* a custom class instance
* that class holds the subflow’s underlying function
That is very likely the problem.
When a flow runs remotely in another container/process, Prefect has to serialize the parameters. Custom class instances and function objects are generally not safe to pass as flow parameters for remote execution. In practice, they often won’t survive serialization the way you expect.
So instead of this pattern:
python
obj = MyClass(fn=some_function)
child_flow(obj)
use something serializable, like:
python
@flow
def child_flow(config: dict):
fn_name = config["fn_name"]
...
For example:
python
from prefect import flow
FUNCTIONS = {}
def register(fn):
FUNCTIONS[fn.__name__] = fn
return fn
@register
def do_work(x):
return x * 10
@flow
def child_flow(payload: dict):
fn = FUNCTIONS[payload["fn_name"]]
result = fn(payload["x"])
return {"result": result}
@flow
def parent_flow():
child_state = child_flow(
{"fn_name": "do_work", "x": 5},
return_state=True
)
if child_state.is_completed():
return child_state.result()
return child_state.result(raise_on_failure=False)
That way you pass only JSON-serializable data between runs.
---
Recommended approach for your case
1. Do not pass the class instance itself to the remotely run subflow.
2. Do not pass a function object as a flow parameter.
3. Pass only serializable inputs:
* strings
* numbers
* dicts/lists
* simple Pydantic models
4. In the child flow, reconstruct whatever object you need from that serializable config.
5. Use return_state=True in the parent if you need access to both success/failure details.
---
If you want, I can help rewrite your exact parent/subflow/class pattern into a Prefect-safe version. If you paste a small version of your code, I’ll adapt it.