Skip to content

[Bug]: ResultManager:processEvents (second events modifies first arriving event) which leads to unexpected behavior and race conditions #412

Description

@RonaldMarske

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

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

Labels

questionFurther information is requested

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions