What happened?
I'm currently dealing with the A2A SDK version 0.3.10 (0.3.13 still has the same bug).
The case happens in RestHandler:sendMessage with configuration blocking: false and pushNotification enabled.
Expectation
Within the A2A Executor, i'm publishing a task with the state "submitted" and shortly after that an status update with a failed state, due to the non blocking case i'd expect the HTTP Response to contain exactly this task.
Result
Within the A2A Executor, i'm publishing a task with the state "submitted" and shortly after that an status update with a failed state. The SendMessage endpoint within DefaultRequestHandler is opening a promise and calls the _processEvents method to resolve the promise. So far so good, this works as expected, within the promise is only the submitted task state, and the event is moving forward to be send back to the sender.
At the same time the status-update event arrives and the ResultManager is processing the event and updates this.currentTask - updates the history and changes the message.
since the first event - still traveling through the code and this.currentTask is actually the same object, the second event updates the "submitted" event which then leads to an unexpected behaviour.
Relevant log output
// Chronological correct
// 1. Task
defaultRequestHandler::_processEvent before ResultManager.processEvent (this.currentTask) {
kind: 'task',
artifacts: [],
id: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
status: { state: 'submitted', timestamp: '2026-04-22T11:28:12.823Z' },
history: [
{
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
extensions: [],
kind: 'message',
messageId: '00000000-0000-1000-a008-000000000002',
parts: [Array],
role: 'user',
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95'
}
]
}
defaultRequestHandler::_processEvent after ResultManager.processEvent (this.currentTask) {
kind: 'task',
artifacts: [],
id: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
status: { state: 'submitted', timestamp: '2026-04-22T11:28:12.823Z' },
history: [
{
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
extensions: [],
kind: 'message',
messageId: '00000000-0000-1000-a008-000000000002',
parts: [Array],
role: 'user',
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95'
}
]
}
defaultRequestHandler.sendMessage return Promise value: {
kind: 'task',
artifacts: [],
id: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
status: { state: 'submitted', timestamp: '2026-04-22T11:28:12.823Z' },
history: [
{
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
extensions: [],
kind: 'message',
messageId: '00000000-0000-1000-a008-000000000002',
parts: [Array],
role: 'user',
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95'
}
]
}
//Status Update arrives in DefaultRequestManager::_processEvents
defaultRequestHandler::_processEvent before ResultManager.processEvent (this.currentTask) {
kind: 'status-update',
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
status: {
state: 'failed',
message: {
kind: 'message',
role: 'agent',
messageId: 'f0f86e4f-63c7-48c7-9e35-46be06d52392',
parts: [Array],
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201'
},
timestamp: '2026-04-22T11:28:13.159Z'
}
}
defaultRequestHandler::_processEvent after ResultManager.processEvent (this.currentTask) {
kind: 'status-update',
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
status: {
state: 'failed',
message: {
kind: 'message',
role: 'agent',
messageId: 'f0f86e4f-63c7-48c7-9e35-46be06d52392',
parts: [Array],
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201'
},
timestamp: '2026-04-22T11:28:13.159Z'
}
}
Express server returning response (Here the task changed due to the previous events)
This should be the initial task:
{
kind: 'task',
artifacts: [],
id: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
status: {
state: 'failed',
message: {
kind: 'message',
role: 'agent',
messageId: 'f0f86e4f-63c7-48c7-9e35-46be06d52392',
parts: [ { kind: 'text', text: 'Internal Server Error' } ],
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201'
},
timestamp: '2026-04-22T11:28:13.159Z'
},
history: [
{
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201',
extensions: [],
kind: 'message',
messageId: '00000000-0000-1000-a008-000000000002',
parts: [ { kind: 'text', text: 'Invocation2 message' } ],
role: 'user',
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95'
},
{
kind: 'message',
role: 'agent',
messageId: 'f0f86e4f-63c7-48c7-9e35-46be06d52392',
parts: [ { kind: 'text', text: 'Internal Server Error' } ],
taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95',
contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201'
}
]
}
Code of Conduct
What happened?
I'm currently dealing with the A2A SDK version 0.3.10 (0.3.13 still has the same bug).
The case happens in RestHandler:sendMessage with configuration
blocking: falseand pushNotification enabled.Expectation
Within the A2A Executor, i'm publishing a task with the state "submitted" and shortly after that an status update with a failed state, due to the non blocking case i'd expect the HTTP Response to contain exactly this task.
Result
Within the A2A Executor, i'm publishing a task with the state "submitted" and shortly after that an status update with a failed state. The SendMessage endpoint within DefaultRequestHandler is opening a promise and calls the _processEvents method to resolve the promise. So far so good, this works as expected, within the promise is only the submitted task state, and the event is moving forward to be send back to the sender.
At the same time the status-update event arrives and the ResultManager is processing the event and updates
this.currentTask- updates the history and changes the message.since the first event - still traveling through the code and
this.currentTaskis actually the same object, the second event updates the "submitted" event which then leads to an unexpected behaviour.Relevant log output
// Chronological correct // 1. Task defaultRequestHandler::_processEvent before ResultManager.processEvent (this.currentTask) { kind: 'task', artifacts: [], id: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', status: { state: 'submitted', timestamp: '2026-04-22T11:28:12.823Z' }, history: [ { contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', extensions: [], kind: 'message', messageId: '00000000-0000-1000-a008-000000000002', parts: [Array], role: 'user', taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95' } ] } defaultRequestHandler::_processEvent after ResultManager.processEvent (this.currentTask) { kind: 'task', artifacts: [], id: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', status: { state: 'submitted', timestamp: '2026-04-22T11:28:12.823Z' }, history: [ { contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', extensions: [], kind: 'message', messageId: '00000000-0000-1000-a008-000000000002', parts: [Array], role: 'user', taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95' } ] } defaultRequestHandler.sendMessage return Promise value: { kind: 'task', artifacts: [], id: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', status: { state: 'submitted', timestamp: '2026-04-22T11:28:12.823Z' }, history: [ { contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', extensions: [], kind: 'message', messageId: '00000000-0000-1000-a008-000000000002', parts: [Array], role: 'user', taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95' } ] } //Status Update arrives in DefaultRequestManager::_processEvents defaultRequestHandler::_processEvent before ResultManager.processEvent (this.currentTask) { kind: 'status-update', taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', status: { state: 'failed', message: { kind: 'message', role: 'agent', messageId: 'f0f86e4f-63c7-48c7-9e35-46be06d52392', parts: [Array], taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201' }, timestamp: '2026-04-22T11:28:13.159Z' } } defaultRequestHandler::_processEvent after ResultManager.processEvent (this.currentTask) { kind: 'status-update', taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', status: { state: 'failed', message: { kind: 'message', role: 'agent', messageId: 'f0f86e4f-63c7-48c7-9e35-46be06d52392', parts: [Array], taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201' }, timestamp: '2026-04-22T11:28:13.159Z' } } Express server returning response (Here the task changed due to the previous events) This should be the initial task: { kind: 'task', artifacts: [], id: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', status: { state: 'failed', message: { kind: 'message', role: 'agent', messageId: 'f0f86e4f-63c7-48c7-9e35-46be06d52392', parts: [ { kind: 'text', text: 'Internal Server Error' } ], taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201' }, timestamp: '2026-04-22T11:28:13.159Z' }, history: [ { contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201', extensions: [], kind: 'message', messageId: '00000000-0000-1000-a008-000000000002', parts: [ { kind: 'text', text: 'Invocation2 message' } ], role: 'user', taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95' }, { kind: 'message', role: 'agent', messageId: 'f0f86e4f-63c7-48c7-9e35-46be06d52392', parts: [ { kind: 'text', text: 'Internal Server Error' } ], taskId: '0ab92ff0-dc82-4ea5-a172-af7bae8f1e95', contextId: '65f97c7a-58b1-4da7-a901-ddcec3517201' } ] }Code of Conduct