A failing Agno workflow run now writes ERROR to the database first, then sends StepError and WorkflowError. Before, a streaming run that failed halfway emitted its WorkflowError first and saved the failure after it, so a client that stopped reading at that event could lose the run entirely.
A workflow that resumed after a pause could also fail, save ERROR to the database, and still leave its tracked stream stuck at PAUSED.
The outputs of steps that completed before the error stay on the run.

run = workflow.get_last_run_output()
run.status # RunStatus.error
[(s.step_name, s.success) for s in run.step_results]
# [("fetch_orders", True), ("charge_cards", False)]Agno also stopped retrying guardrail rejections in nested workflows. Those retries had replayed the side effects of earlier child steps.
Learn more about workflow sessions, and the run records they store, in the documentation.
Frequently asked questions
A streaming Agno workflow used to emit its WorkflowError event before it saved the failure. A client that stopped reading at that event could lose the run. Agno now saves the run as ERROR first and then sends StepError and WorkflowError.
A resumed run could fail and write ERROR to the database while its tracked stream still showed PAUSED. Agno now records the final status before the stream ends.
Yes. When an Agno workflow run fails, the steps that completed before the error keep their output in run.step_results.



