Task, TaskStatus, and TaskState
A Task carries one TaskStatus, whose state is one of nine TaskState values, and the specification names those values without a table of the transitions between them.
Your planner holds three tasks at once: the tests on test-runner, the review on code-reviewer, and the deploy on deployer. Each is a Task with a status, and the planner's next action turns on status.state: wait, act, or stop.
When you finish this section, you can read every field of a Task, classify every TaskState value, and say which transitions the specification defines.
Task
Task: the basic unit of work in A2A, with a unique id. The proto gives Task six fields and marks id and status REQUIRED. The server creates the id, and a client cannot supply one.
The optional fields are contextId, artifacts, history, and metadata. contextId, Artifact and chunks, and GetTask and ListTasks cover the first three in turn. Figure 3.4 lays out task 3d8f7801 from the blocking run.
TaskStatus
TaskStatus: the current status of a task, with state REQUIRED and message and timestamp optional. The message belongs to the status, and the timestamp is the ISO 8601 time when the status was recorded.
A task has one status at a time, and the previous status message can move into history, as 06-input-required.http shows.
TaskState
The enum TaskState has nine values, numbered 0 to 8. In JSON, a state travels as its name.
Terminal state: a state that ends the task for good. The proto marks four values as terminal.
Interrupted state: a state in which the task waits for something from outside the agent. The proto marks two values as interrupted.
Active state: this manual's name for TASK_STATE_SUBMITTED and TASK_STATE_WORKING, which the proto puts in neither group.
| Value | Number | Class | In the kit |
|---|---|---|---|
TASK_STATE_UNSPECIFIED | 0 | none | never sent |
TASK_STATE_SUBMITTED | 1 | active | every new task, 04-polling.http |
TASK_STATE_WORKING | 2 | active | the suite runs, 05-streaming.http |
TASK_STATE_COMPLETED | 3 | terminal | the tests end, 03-blocking-task.http |
TASK_STATE_FAILED | 4 | terminal | commit deadbee, 09-failed.http |
TASK_STATE_CANCELED | 5 | terminal | after CancelTask, 10-cancel.http |
TASK_STATE_INPUT_REQUIRED | 6 | interrupted | the base branch question, 06-input-required.http |
TASK_STATE_REJECTED | 7 | terminal | a production deploy, 08-rejected.http |
TASK_STATE_AUTH_REQUIRED | 8 | interrupted | waiting for an operator, 07-auth-required.http |
TASK_STATE_UNSPECIFIED is the proto3 zero value, for a task whose state is unknown. The kit never sends it, so treat it and any unknown name as an error.
A client needs both named sets, because a blocking SendMessage returns at a terminal or an interrupted state, as SendMessage shows.
The transitions the specification allows
The specification says that tasks move through a defined lifecycle, yet neither its prose nor the proto has a transition table. What it says about transitions fits in four rules:
- Input: an agent can ask for more input during the work by moving a task to the
input-requiredstate. That is the 0.3 name ofTASK_STATE_INPUT_REQUIRED(conflict D37). - Authorization: an agent "MUST transition the TaskState to
TASK_STATE_AUTH_REQUIRED" to ask for it, and can resume without a client message. - Rejection: an agent can reject a task when it creates it or later.
- Finality: a terminal task refuses messages, cancellation, and subscription.
The migration guide says that 1.0 made the state transitions for cancellation clearer, and the specification lists none (conflict D38). The extensions guide lists extensions that add new states or transitions. It also says that extensions should use the existing enum values (conflict D29). Expect only the nine values.
With no table in the protocol, an agent's transitions are whatever its code emits. Figure 3.5 collects every transition the kit's agents make.
The deployer leaves TASK_STATE_AUTH_REQUIRED with no message from the client, as the specification allows, and rejects straight from TASK_STATE_SUBMITTED. The reference SDK enforces no table either, so accept any transition out of a state that is not terminal.
A terminal task refuses a message on its taskId and SubscribeToTask with UnsupportedOperationError, and CancelTask with TaskNotCancelableError. CancelTask and terminal states covers the four endings, and the state table lists the client's next step for each value.
A2A protocol 1.0.1 · 3303592 · 2026-05-28 · Edition 2026.10