From 4b18ceaa04815b53f69af68fbcbbed166ee21080 Mon Sep 17 00:00:00 2001 From: Kabir Khan Date: Tue, 17 Mar 2026 17:22:49 +0000 Subject: [PATCH] fix: Reject messages to tasks in terminal states Per A2A spec CORE-SEND-002, SendMessage must return UnsupportedOperationError when attempting to send messages to tasks in terminal states (completed, canceled, rejected, failed). Added validation in DefaultRequestHandler.initMessageSend() to check if the existing task is in a terminal state (using TaskState.isFinal()) and throw UnsupportedOperationError before the message reaches the AgentExecutor. This fixes the issue on all three transports (JSON-RPC, gRPC, HTTP+JSON) since they all use the same DefaultRequestHandler code path. Fixes #741 Co-Authored-By: Claude Sonnet 4.5 --- .../a2a/server/requesthandlers/DefaultRequestHandler.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server-common/src/main/java/io/a2a/server/requesthandlers/DefaultRequestHandler.java b/server-common/src/main/java/io/a2a/server/requesthandlers/DefaultRequestHandler.java index fdc6ee11d..5f5d52523 100644 --- a/server-common/src/main/java/io/a2a/server/requesthandlers/DefaultRequestHandler.java +++ b/server-common/src/main/java/io/a2a/server/requesthandlers/DefaultRequestHandler.java @@ -1034,6 +1034,13 @@ private MessageSendSetup initMessageSend(MessageSendParams params, ServerCallCon task.id(), task.contextId(), messageContextId)); } + // Per spec CORE-SEND-002: Reject messages to tasks in terminal states + if (task.status().state().isFinal()) { + throw new UnsupportedOperationError(null, String.format( + "Cannot send message to task %s: task is in terminal state %s and cannot accept further messages", + task.id(), task.status().state()), null); + } + LOGGER.debug("Found task updating with message {}", params.message()); task = taskManager.updateWithMessage(params.message(), task);