Summary
A functional workflow loses user state when it resumes a human-in-the-loop run with responses={...} and no checkpoint_id.
Reproduction
from agent_framework import RunContext, step, workflow
@step
async def seed_state(ctx: RunContext) -> str:
ctx.set_state("marker", "ok")
return "seeded"
@workflow
async def stateful_review(data: str, ctx: RunContext) -> str:
value = await seed_state()
answer = await ctx.request_info("question", response_type=str, request_id="r1")
return f"{ctx.get_state('marker', 'MISSING')}:{value}:{answer}"
caller = stateful_review.build()
first = await caller.run("input")
resumed = await caller.run(responses={"r1": "ok"})
On current main, the resumed output is:
The seed_state step is replayed from its cache, so its body is not executed during the response-only resume. The new RunContext therefore has an empty _state.
Expected behavior
The response-only resume should restore the user state captured when the workflow suspended and return:
The same workflow already preserves the state when resumed with a checkpoint_id, which demonstrates that state persistence is intended for HITL resumes.
Impact
This can silently change workflow decisions and outputs in normal multi-turn HITL flows whenever a completed cached step initialized or updated workflow state before requesting input. The workflow appears to resume successfully, but state-dependent logic observes missing values.
Related context
The review discussion on the original functional workflow implementation in #4238 identified that response-only resumes restore cached step outputs but not workflow state. This issue tracks the unresolved follow-up. It is distinct from #8292, which concerns cached-result swaps between concurrent calls to the same @step.
Summary
A functional workflow loses user state when it resumes a human-in-the-loop run with
responses={...}and nocheckpoint_id.Reproduction
On current
main, the resumed output is:The
seed_statestep is replayed from its cache, so its body is not executed during the response-only resume. The newRunContexttherefore has an empty_state.Expected behavior
The response-only resume should restore the user state captured when the workflow suspended and return:
The same workflow already preserves the state when resumed with a
checkpoint_id, which demonstrates that state persistence is intended for HITL resumes.Impact
This can silently change workflow decisions and outputs in normal multi-turn HITL flows whenever a completed cached step initialized or updated workflow state before requesting input. The workflow appears to resume successfully, but state-dependent logic observes missing values.
Related context
The review discussion on the original functional workflow implementation in #4238 identified that response-only resumes restore cached step outputs but not workflow state. This issue tracks the unresolved follow-up. It is distinct from #8292, which concerns cached-result swaps between concurrent calls to the same
@step.