Skip to content

A2AAgentWorker pre-executes flow before user's first message, causing InputMessageStep to consume trigger message as form data #151

@groganz

Description

@groganz

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

  1. Build a WayflowFlow whose first node (after StartNode) is an InputMessageStep that expects structured input (e.g. required fields in its schema).
  2. Send any initial message/send request — a trigger message that does not contain the expected form fields.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions