Summary
When a WayflowFlow containing an InputMessageStep receives its first A2A message/send call, A2AAgentWorker.run_task pre-executes the conversation before appending the user's message:
if isinstance(self.assistant, WayflowFlow) and any(
isinstance(step, InputMessageStep) for step in self.assistant.steps.values()
):
await conversation.execute_async()
The pre-execute runs the flow until it yields at the first InputMessageStep (setting asked_user = True in the step's internal context). The worker then immediately appends the user's incoming message and calls execute_async() again. Because asked_user is now True, the InputMessageStep treats that incoming message as the user's form response rather than a trigger — and passes it downstream without ever returning input-required to the caller.
Steps to reproduce
- Build a
WayflowFlow whose first node (after StartNode) is an InputMessageStep that expects structured input (e.g. required fields in its schema).
- Send any initial
message/send request — a trigger message that does not contain the expected form fields.
- Observe: the
InputMessageStep consumes the trigger message as if it were the user's form submission and passes its raw content to the next step, instead of returning state: input-required so the client can collect proper input from the user.
Expected behaviour
When the flow reaches an InputMessageStep and the user has not yet provided the expected input, the A2A task should transition to input-required. The client gets a chance to render the appropriate UI, collect the user's response, and resume the task with the actual form data.
Actual behaviour
The pre-execute sets asked_user = True, so the very next execute_async() call (triggered by the trigger message) skips the "ask" phase and immediately treats the trigger message as the user's answer. If the trigger message does not contain the expected fields, downstream steps receive incomplete or wrong data, typically resulting in a runtime error and state: failed.
Context
wayflowcore 26.1.1
A2AAgentWorker.run_task in wayflowcore/agentserver/a2a/_worker.py
- The pre-execute pattern makes sense when there are non-interactive steps (e.g.
ApiNode, LlmNode) before the first InputMessageStep. In that case, running up to the first yield is useful. But when the InputMessageStep is the first meaningful step in the flow, the pre-execute is a no-op that leaves the step in the wrong state, causing the trigger message to be misinterpreted.
Suggested fix
Guard the pre-execute on whether any non-interactive steps actually precede the first InputMessageStep. If the first InputMessageStep is reached immediately (no intermediate work), skip the pre-execute so the first user message hits the step in its initial state and the flow can correctly return input-required.
Alternatively, document clearly that callers are expected to supply the InputMessageStep's required input in the first message/send call, and that returning input-required on the first call is not supported for WayflowFlow agents.
Summary
When a
WayflowFlowcontaining anInputMessageStepreceives its first A2Amessage/sendcall,A2AAgentWorker.run_taskpre-executes the conversation before appending the user's message:The pre-execute runs the flow until it yields at the first
InputMessageStep(settingasked_user = Truein the step's internal context). The worker then immediately appends the user's incoming message and callsexecute_async()again. Becauseasked_useris nowTrue, theInputMessageSteptreats that incoming message as the user's form response rather than a trigger — and passes it downstream without ever returninginput-requiredto the caller.Steps to reproduce
WayflowFlowwhose first node (afterStartNode) is anInputMessageStepthat expects structured input (e.g. required fields in its schema).message/sendrequest — a trigger message that does not contain the expected form fields.InputMessageStepconsumes the trigger message as if it were the user's form submission and passes its raw content to the next step, instead of returningstate: input-requiredso the client can collect proper input from the user.Expected behaviour
When the flow reaches an
InputMessageStepand the user has not yet provided the expected input, the A2A task should transition toinput-required. The client gets a chance to render the appropriate UI, collect the user's response, and resume the task with the actual form data.Actual behaviour
The pre-execute sets
asked_user = True, so the very nextexecute_async()call (triggered by the trigger message) skips the "ask" phase and immediately treats the trigger message as the user's answer. If the trigger message does not contain the expected fields, downstream steps receive incomplete or wrong data, typically resulting in a runtime error andstate: failed.Context
wayflowcore26.1.1A2AAgentWorker.run_taskinwayflowcore/agentserver/a2a/_worker.pyApiNode,LlmNode) before the firstInputMessageStep. In that case, running up to the first yield is useful. But when theInputMessageStepis the first meaningful step in the flow, the pre-execute is a no-op that leaves the step in the wrong state, causing the trigger message to be misinterpreted.Suggested fix
Guard the pre-execute on whether any non-interactive steps actually precede the first
InputMessageStep. If the firstInputMessageStepis reached immediately (no intermediate work), skip the pre-execute so the first user message hits the step in its initial state and the flow can correctly returninput-required.Alternatively, document clearly that callers are expected to supply the
InputMessageStep's required input in the firstmessage/sendcall, and that returninginput-requiredon the first call is not supported forWayflowFlowagents.