KubeMQ
AiwayAI Agents (A2A)

Error Handling

A2A error codes (-32001 to -32004), JSON-RPC base codes, the transport vs application error distinction, and retry strategy for AI agent calls.

Every A2A response is a JSON-RPC 2.0 envelope, so failures come back as a structured error object with a numeric code and a message — never as a raw HTTP error. This page is the field guide to those codes: which ones the gateway raises, which come from the agent, and how to decide whether to retry.

Overview

The A2A gateway returns errors at HTTP 200 with a JSON-RPC error body for anything it can parse as a request. A failed call looks like this:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32002,
    "message": "agent not found: nonexistent-agent"
  }
}

There are two families of codes:

  • JSON-RPC base codes (-32700, -32600, -32601, -32602, -32603, -32010) — shared with the MCP connector and raised by the gateway for malformed requests, bad methods, or auth failures.
  • A2A-specific codes (-32001 to -32004) — raised when the gateway routes to a registered agent but the call to that agent fails (timeout, missing agent, rejection, or an unparseable reply).

JSON-RPC base codes

These are the standard JSON-RPC 2.0 codes returned by the shared HTTP layer for requests that never reach an agent — the body or method is wrong, or authentication failed.

CodeConstantMeaningTypical cause
-32700JSONRPCParseErrorParse errorInvalid JSON body, or Content-Type is not application/json
-32600JSONRPCInvalidRequestInvalid requestMissing method, wrong jsonrpc version, or an invalid agent_id format
-32601JSONRPCMethodNotFoundMethod not foundUnknown method for the endpoint
-32602JSONRPCInvalidParamsInvalid paramsThe params object failed validation
-32603JSONRPCInternalErrorInternal errorUnexpected gateway-side failure
-32010jsonrpcAuthErrorAuthentication failureMissing or invalid JWT on a protected route

The agent_id in the URL path is validated before routing. An invalid format (for example uppercase characters) is rejected with -32600 — the request never reaches an agent. See Authentication for the -32010 auth flow.

A2A-specific codes

These codes are raised by the gateway when it has a registered agent to route to but the outbound HTTP call to that agent fails.

CodeConstantMeaning
-32001jsonrpcAgentTimeoutThe agent did not respond within the request timeout
-32002jsonrpcAgentNotFoundNo agent is registered under that agent_id
-32003jsonrpcAgentUnavailableThe agent rejected the request (unreachable or returned a 5xx)
-32004jsonrpcInvalidResponseThe agent replied, but the body was not valid JSON-RPC

The request timeout that drives -32001 defaults to DefaultTimeoutSeconds (300s) and is capped by MaxTimeoutSeconds (3600s); per-call, set params.configuration.timeout (seconds) to lower it. The same code is also emitted as a task.error envelope when an SSE stream hits its idle timeout (MaxSSEIdleSeconds, default 300s) — see SSE behavior.

Transport vs application errors

Underneath the JSON-RPC codes, the gateway's virtual subscriber draws a sharp line between a call the agent never processed and one it processed but rejected. This distinction is what lets you decide whether retrying is safe.

The agent's reply carries an Executed flag:

  • Executed: false — a transport error. The agent never handled the request, so retrying (against another instance, or after a backoff) is safe. Mapped to -32001 (timeout), -32002 (not found), or -32003 (unavailable).
  • Executed: true — the agent did process the request. A 2xx is a success; a 4xx/5xx body is an application error the agent chose to return. Retrying the same call will produce the same result, so handle it as a business outcome rather than blindly retrying.
ConditionGateway resultClassification
Connection refused / DNS failureExecuted: false · "agent unreachable"Transport
HTTP timeout (deadline exceeded)Executed: false · "agent timeout"Transport
HTTP 502 / 503 / 504Executed: false · "agent unavailable: 50x"Transport
Response body exceeds AgentMaxResponseBytes (10 MB)Executed: false · "agent response too large"Transport
Concurrency limit reached (AgentMaxConcurrency, 100)Executed: false · "server busy: concurrency limit reached"Transport
HTTP 200–299Executed: true · response bodySuccess
HTTP 400 / 401 / 403 / 404 / 409 / 422 / 500Executed: true · response bodyApplication

Retry strategy

A safe default: retry transport errors, surface application errors.

  • -32002 (agent not found) — the target is not in the registry. Do not retry the same agent_id; re-resolve the agent (it may have expired its TTL) or register it first.
  • -32001 (timeout) — retry with backoff. If it persists, the agent is overloaded or the per-call timeout is too low for the workload; raise params.configuration.timeout.
  • -32003 (unavailable) and Executed: false — the agent never ran the request; retry with exponential backoff, optionally against a healthy instance.
  • -32004 (invalid response) — the agent is misbehaving (non-JSON-RPC body). Retrying rarely helps; treat it as a bug in the agent.
  • JSON-RPC base codes (-32600, -32602, -32700) — the request itself is wrong. Fix the payload; retrying unchanged will fail identically.
  • Application errors (Executed: true with a 4xx/5xx body) — these are the agent's deliberate response. Handle them as domain outcomes, not infrastructure faults.

Examples

The snippets below trigger each error family against a running gateway: a missing agent (-32002), malformed JSON-RPC requests (base codes), and a timeout (-32001).

Agent not found (-32002)

Send a message/send to an agent_id that is not registered. The gateway returns a JSON-RPC error with code -32002.

curl -X POST http://localhost:9090/a2a/nonexistent-agent \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "message/send",
    "params": {"message": {"parts": [{"text": "Hello?"}]}}
  }'
# => {"jsonrpc":"2.0","id":1,"error":{"code":-32002,"message":"agent not found: nonexistent-agent"}}
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;

const string KubeMqUrl = "http://localhost:9090";
const string AgentId = "nonexistent-agent";

var payload = new JsonObject
{
    ["jsonrpc"] = "2.0",
    ["id"] = 1,
    ["method"] = "message/send",
    ["params"] = new JsonObject
    {
        ["message"] = new JsonObject
        {
            ["parts"] = new JsonArray(new JsonObject { ["text"] = "Hello?" })
        }
    }
};

using var client = new HttpClient();
var resp = await client.PostAsync(
    $"{KubeMqUrl}/a2a/{AgentId}",
    new StringContent(payload.ToJsonString(), Encoding.UTF8, "application/json"));

var body = await resp.Content.ReadAsStringAsync();
var data = JsonNode.Parse(body)!;
Console.WriteLine(JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }));

var error = data["error"];
Console.WriteLine($"\nError code:    {error?["code"]}");
Console.WriteLine($"Error message: {error?["message"]}");

var code = error?["code"]?.GetValue<int>();
if (code == -32002)
    Console.WriteLine("\nAgent-not-found error (-32002) received as expected!");
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
)

const (
	kubemqURL = "http://localhost:9090"
	agentID   = "nonexistent-agent"
)

func main() {
	payload := map[string]interface{}{
		"jsonrpc": "2.0",
		"id":      1,
		"method":  "message/send",
		"params": map[string]interface{}{
			"message": map[string]interface{}{
				"parts": []map[string]interface{}{{"text": "Hello?"}},
			},
		},
	}

	data, _ := json.Marshal(payload)
	resp, err := http.Post(kubemqURL+"/a2a/"+agentID, "application/json", bytes.NewReader(data))
	if err != nil {
		fmt.Fprintf(os.Stderr, "Request failed: %v\n", err)
		os.Exit(1)
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	var pretty bytes.Buffer
	json.Indent(&pretty, body, "", "  ")
	fmt.Println(pretty.String())

	var result map[string]interface{}
	json.Unmarshal(body, &result)

	errorObj, _ := result["error"].(map[string]interface{})
	code, _ := errorObj["code"].(float64)
	msg, _ := errorObj["message"].(string)
	fmt.Printf("\nError code:    %.0f\n", code)
	fmt.Printf("Error message: %s\n", msg)

	if int(code) != -32002 {
		fmt.Fprintf(os.Stderr, "Expected -32002, got %.0f\n", code)
		os.Exit(1)
	}
	fmt.Println("\nAgent-not-found error (-32002) received as expected!")
}
import com.fasterxml.jackson.databind.ObjectMapper;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.Map;

public class Client {

    static final String KUBEMQ_URL = "http://localhost:9090";
    static final String AGENT_ID = "nonexistent-agent";
    static final ObjectMapper MAPPER = new ObjectMapper();

    public static void main(String[] args) throws Exception {
        var payload = Map.of(
            "jsonrpc", "2.0",
            "id", 1,
            "method", "message/send",
            "params", Map.of(
                "message", Map.of("parts", List.of(Map.of("text", "Hello?")))
            )
        );

        var client = HttpClient.newHttpClient();
        var req = HttpRequest.newBuilder()
            .uri(URI.create(KUBEMQ_URL + "/a2a/" + AGENT_ID))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(MAPPER.writeValueAsString(payload)))
            .build();
        var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
        var data = MAPPER.readTree(resp.body());
        System.out.println(MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(data));

        var error = data.path("error");
        System.out.println("\nError code:    " + error.path("code").asInt());
        System.out.println("Error message: " + error.path("message").asText());

        assert error.path("code").asInt() == -32002 : "Expected -32002, got " + error.path("code").asInt();
        System.out.println("\nAgent-not-found error (-32002) received as expected!");
    }
}
import asyncio
import json

import httpx

KUBEMQ_URL = "http://localhost:9090"
AGENT_ID = "nonexistent-agent"


async def main() -> None:
    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "message/send",
        "params": {
            "message": {"parts": [{"text": "Hello?"}]},
        },
    }

    async with httpx.AsyncClient() as client:
        resp = await client.post(f"{KUBEMQ_URL}/a2a/{AGENT_ID}", json=payload)
        data = resp.json()
        print(json.dumps(data, indent=2))

        error = data.get("error", {})
        print(f"\nError code:    {error.get('code')}")
        print(f"Error message: {error.get('message')}")

        assert error.get("code") == -32002, f"Expected -32002, got {error.get('code')}"
        print("\nAgent-not-found error (-32002) received as expected!")


if __name__ == "__main__":
    asyncio.run(main())
const KUBEMQ_URL = "http://localhost:9090";

async function main() {
  const request = {
    jsonrpc: "2.0",
    id: 1,
    method: "message/send",
    params: {
      message: { parts: [{ text: "Hello?" }] },
    },
  };

  console.log("Sending to nonexistent agent...");

  const resp = await fetch(`${KUBEMQ_URL}/a2a/nonexistent-agent`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(request),
  });

  const data = await resp.json();
  console.log("Response:", JSON.stringify(data, null, 2));

  if (data.error) {
    console.log(`\nError code:    ${data.error.code} (expect -32002)`);
    console.log(`Error message: ${data.error.message}`);
    console.log(`Match:         ${data.error.code === -32002}`);
  }
}

main().catch(console.error);

Invalid request (JSON-RPC base codes)

Malformed payloads are rejected by the gateway with base codes — invalid JSON or a wrong Content-Type yields -32700, while a missing method or wrong jsonrpc version yields -32600.

# Invalid JSON body -> -32700
curl -X POST http://localhost:9090/a2a/echo-agent-01 \
  -H "Content-Type: application/json" \
  -d '{invalid json!!!}'

# Missing method field -> -32600
curl -X POST http://localhost:9090/a2a/echo-agent-01 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": 1, "params": {}}'

# Bad jsonrpc version -> -32600
curl -X POST http://localhost:9090/a2a/echo-agent-01 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "1.0", "id": 1, "method": "message/send", "params": {}}'
using System.Text;
using System.Text.Json.Nodes;

const string KubeMqUrl = "http://localhost:9090";
const string AgentId = "echo-agent-01";

using var client = new HttpClient();

Console.WriteLine("=== Test 1: Invalid JSON ===");
var resp = await client.PostAsync(
    $"{KubeMqUrl}/a2a/{AgentId}",
    new StringContent("{invalid json!!!}", Encoding.UTF8, "application/json"));
var data = JsonNode.Parse(await resp.Content.ReadAsStringAsync())!;
var error = data["error"];
Console.WriteLine($"  Code: {error?["code"]} (expected -32700)");
Console.WriteLine($"  Message: {error?["message"]}");

Console.WriteLine("\n=== Test 2: Missing method field ===");
var payload2 = new JsonObject
{
    ["jsonrpc"] = "2.0",
    ["id"] = 1,
    ["params"] = new JsonObject()
};
resp = await client.PostAsync(
    $"{KubeMqUrl}/a2a/{AgentId}",
    new StringContent(payload2.ToJsonString(), Encoding.UTF8, "application/json"));
data = JsonNode.Parse(await resp.Content.ReadAsStringAsync())!;
error = data["error"];
Console.WriteLine($"  Code: {error?["code"]} (expected -32600)");
Console.WriteLine($"  Message: {error?["message"]}");

Console.WriteLine("\n=== Test 3: Bad jsonrpc version ===");
var payload3 = new JsonObject
{
    ["jsonrpc"] = "1.0",
    ["id"] = 1,
    ["method"] = "message/send",
    ["params"] = new JsonObject()
};
resp = await client.PostAsync(
    $"{KubeMqUrl}/a2a/{AgentId}",
    new StringContent(payload3.ToJsonString(), Encoding.UTF8, "application/json"));
data = JsonNode.Parse(await resp.Content.ReadAsStringAsync())!;
error = data["error"];
Console.WriteLine($"  Code: {error?["code"]} (expected -32600)");
Console.WriteLine($"  Message: {error?["message"]}");

Console.WriteLine("\nAll invalid request errors demonstrated!");
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

const (
	kubemqURL = "http://localhost:9090"
	agentID   = "echo-agent-01"
)

func main() {
	fmt.Println("=== Test 1: Invalid JSON ===")
	req, _ := http.NewRequest("POST", kubemqURL+"/a2a/"+agentID, strings.NewReader("{invalid json!!!}"))
	req.Header.Set("Content-Type", "application/json")
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Request failed: %v\n", err)
		os.Exit(1)
	}
	body, _ := io.ReadAll(resp.Body)
	resp.Body.Close()
	var data map[string]interface{}
	json.Unmarshal(body, &data)
	errorObj, _ := data["error"].(map[string]interface{})
	code, _ := errorObj["code"].(float64)
	fmt.Printf("  Code: %.0f (expected -32700)\n", code)
	fmt.Printf("  Message: %v\n", errorObj["message"])

	fmt.Println("\n=== Test 2: Missing method field ===")
	payload2, _ := json.Marshal(map[string]interface{}{
		"jsonrpc": "2.0",
		"id":      1,
		"params":  map[string]interface{}{},
	})
	resp, _ = http.Post(kubemqURL+"/a2a/"+agentID, "application/json", bytes.NewReader(payload2))
	body, _ = io.ReadAll(resp.Body)
	resp.Body.Close()
	json.Unmarshal(body, &data)
	errorObj, _ = data["error"].(map[string]interface{})
	code, _ = errorObj["code"].(float64)
	fmt.Printf("  Code: %.0f (expected -32600)\n", code)
	fmt.Printf("  Message: %v\n", errorObj["message"])

	fmt.Println("\n=== Test 3: Bad jsonrpc version ===")
	payload3, _ := json.Marshal(map[string]interface{}{
		"jsonrpc": "1.0",
		"id":      1,
		"method":  "message/send",
		"params":  map[string]interface{}{},
	})
	resp, _ = http.Post(kubemqURL+"/a2a/"+agentID, "application/json", bytes.NewReader(payload3))
	body, _ = io.ReadAll(resp.Body)
	resp.Body.Close()
	json.Unmarshal(body, &data)
	errorObj, _ = data["error"].(map[string]interface{})
	code, _ = errorObj["code"].(float64)
	fmt.Printf("  Code: %.0f (expected -32600)\n", code)
	fmt.Printf("  Message: %v\n", errorObj["message"])

	fmt.Println("\nAll invalid request errors demonstrated!")
}
import com.fasterxml.jackson.databind.ObjectMapper;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;

public class Client {

    static final String KUBEMQ_URL = "http://localhost:9090";
    static final String AGENT_ID = "echo-agent-01";
    static final ObjectMapper MAPPER = new ObjectMapper();

    public static void main(String[] args) throws Exception {
        var client = HttpClient.newHttpClient();

        System.out.println("=== Test 1: Invalid JSON ===");
        var req = HttpRequest.newBuilder()
            .uri(URI.create(KUBEMQ_URL + "/a2a/" + AGENT_ID))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString("{invalid json!!!}"))
            .build();
        var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
        var data = MAPPER.readTree(resp.body());
        var error = data.path("error");
        System.out.println("  Code: " + error.path("code").asInt() + " (expected -32700)");
        System.out.println("  Message: " + error.path("message").asText());

        System.out.println("\n=== Test 2: Missing method field ===");
        req = HttpRequest.newBuilder()
            .uri(URI.create(KUBEMQ_URL + "/a2a/" + AGENT_ID))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(
                MAPPER.writeValueAsString(Map.of("jsonrpc", "2.0", "id", 1, "params", Map.of()))))
            .build();
        resp = client.send(req, HttpResponse.BodyHandlers.ofString());
        data = MAPPER.readTree(resp.body());
        error = data.path("error");
        System.out.println("  Code: " + error.path("code").asInt() + " (expected -32600)");
        System.out.println("  Message: " + error.path("message").asText());

        System.out.println("\n=== Test 3: Bad jsonrpc version ===");
        req = HttpRequest.newBuilder()
            .uri(URI.create(KUBEMQ_URL + "/a2a/" + AGENT_ID))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(
                MAPPER.writeValueAsString(Map.of(
                    "jsonrpc", "1.0", "id", 1, "method", "message/send", "params", Map.of()))))
            .build();
        resp = client.send(req, HttpResponse.BodyHandlers.ofString());
        data = MAPPER.readTree(resp.body());
        error = data.path("error");
        System.out.println("  Code: " + error.path("code").asInt() + " (expected -32600)");
        System.out.println("  Message: " + error.path("message").asText());

        System.out.println("\nAll invalid request errors demonstrated!");
    }
}
import asyncio

import httpx

KUBEMQ_URL = "http://localhost:9090"
AGENT_ID = "echo-agent-01"


async def main() -> None:
    async with httpx.AsyncClient() as client:
        print("=== Test 1: Invalid JSON ===")
        resp = await client.post(
            f"{KUBEMQ_URL}/a2a/{AGENT_ID}",
            content=b"{invalid json!!!}",
            headers={"Content-Type": "application/json"},
        )
        data = resp.json()
        error = data.get("error", {})
        print(f"  Code: {error.get('code')} (expected -32700)")
        print(f"  Message: {error.get('message')}")

        print("\n=== Test 2: Missing method field ===")
        resp = await client.post(
            f"{KUBEMQ_URL}/a2a/{AGENT_ID}",
            json={"jsonrpc": "2.0", "id": 1, "params": {}},
        )
        data = resp.json()
        error = data.get("error", {})
        print(f"  Code: {error.get('code')} (expected -32600)")
        print(f"  Message: {error.get('message')}")

        print("\n=== Test 3: Bad jsonrpc version ===")
        resp = await client.post(
            f"{KUBEMQ_URL}/a2a/{AGENT_ID}",
            json={"jsonrpc": "1.0", "id": 1, "method": "message/send", "params": {}},
        )
        data = resp.json()
        error = data.get("error", {})
        print(f"  Code: {error.get('code')} (expected -32600)")
        print(f"  Message: {error.get('message')}")

        print("\nAll invalid request errors demonstrated!")


if __name__ == "__main__":
    asyncio.run(main())
const KUBEMQ_URL = "http://localhost:9090";
const AGENT_ID = "echo-agent-01";

async function sendRaw(label: string, url: string, opts: RequestInit) {
  console.log(`=== ${label} ===`);
  try {
    const resp = await fetch(url, opts);
    const text = await resp.text();
    let data: unknown;
    try {
      data = JSON.parse(text);
    } catch {
      data = text;
    }
    console.log(`Status: ${resp.status}`);
    console.log(`Response: ${JSON.stringify(data, null, 2)}\n`);
  } catch (err) {
    console.log(`Error: ${err}\n`);
  }
}

async function main() {
  await sendRaw(
    "Invalid JSON body (expect -32700)",
    `${KUBEMQ_URL}/a2a/${AGENT_ID}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: "{invalid json!!!}",
    },
  );

  await sendRaw(
    "Missing method field (expect -32600)",
    `${KUBEMQ_URL}/a2a/${AGENT_ID}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ jsonrpc: "2.0", id: 1, params: {} }),
    },
  );

  await sendRaw(
    "Wrong JSON-RPC version (expect -32600)",
    `${KUBEMQ_URL}/a2a/${AGENT_ID}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ jsonrpc: "1.0", id: 1, method: "message/send", params: {} }),
    },
  );

  await sendRaw(
    "Wrong Content-Type (expect -32700)",
    `${KUBEMQ_URL}/a2a/${AGENT_ID}`,
    {
      method: "POST",
      headers: { "Content-Type": "text/plain" },
      body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "message/send", params: {} }),
    },
  );

  await sendRaw(
    "Invalid agent_id format (expect -32600)",
    `${KUBEMQ_URL}/a2a/UPPERCASE-BAD`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "message/send", params: {} }),
    },
  );
}

main().catch(console.error);

Timeout (-32001)

Set a short per-call timeout via params.configuration.timeout (seconds) and target an agent that is slower than that. The gateway returns -32001 once the deadline passes.

curl -X POST http://localhost:9090/a2a/slow-agent-01 \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "message/send",
    "params": {
      "message": {"parts": [{"text": "This will timeout"}]},
      "configuration": {"timeout": 1}
    }
  }'
# => {"jsonrpc":"2.0","id":1,"error":{"code":-32001,"message":"agent timeout: slow-agent-01"}}
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;

const string KubeMqUrl = "http://localhost:9090";
const string AgentId = "slow-agent-01";

var payload = new JsonObject
{
    ["jsonrpc"] = "2.0",
    ["id"] = 1,
    ["method"] = "message/send",
    ["params"] = new JsonObject
    {
        ["message"] = new JsonObject
        {
            ["parts"] = new JsonArray(new JsonObject { ["text"] = "This will timeout" })
        },
        ["configuration"] = new JsonObject { ["timeout"] = 1 }
    }
};

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
Console.WriteLine("Sending request with timeout=1 to slow agent (5s delay)...");

var resp = await client.PostAsync(
    $"{KubeMqUrl}/a2a/{AgentId}",
    new StringContent(payload.ToJsonString(), Encoding.UTF8, "application/json"));

var body = await resp.Content.ReadAsStringAsync();
var data = JsonNode.Parse(body)!;
Console.WriteLine(JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }));

var error = data["error"];
Console.WriteLine($"\nError code:    {error?["code"]}");
Console.WriteLine($"Error message: {error?["message"]}");

var code = error?["code"]?.GetValue<int>();
if (code == -32001)
    Console.WriteLine("\nTimeout error (-32001) received as expected!");
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

const (
	kubemqURL = "http://localhost:9090"
	agentID   = "slow-agent-01"
)

func main() {
	payload := map[string]interface{}{
		"jsonrpc": "2.0",
		"id":      1,
		"method":  "message/send",
		"params": map[string]interface{}{
			"message":       map[string]interface{}{"parts": []map[string]interface{}{{"text": "This will timeout"}}},
			"configuration": map[string]interface{}{"timeout": 1},
		},
	}

	data, _ := json.Marshal(payload)
	fmt.Println("Sending request with timeout=1 to slow agent (5s delay)...")

	client := &http.Client{Timeout: 30 * time.Second}
	resp, err := client.Post(kubemqURL+"/a2a/"+agentID, "application/json", bytes.NewReader(data))
	if err != nil {
		fmt.Fprintf(os.Stderr, "Request failed: %v\n", err)
		os.Exit(1)
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	var pretty bytes.Buffer
	json.Indent(&pretty, body, "", "  ")
	fmt.Println(pretty.String())

	var result map[string]interface{}
	json.Unmarshal(body, &result)

	errorObj, _ := result["error"].(map[string]interface{})
	code, _ := errorObj["code"].(float64)
	msg, _ := errorObj["message"].(string)
	fmt.Printf("\nError code:    %.0f\n", code)
	fmt.Printf("Error message: %s\n", msg)

	if int(code) != -32001 {
		fmt.Fprintf(os.Stderr, "Expected -32001, got %.0f\n", code)
		os.Exit(1)
	}
	fmt.Println("\nTimeout error (-32001) received as expected!")
}
import com.fasterxml.jackson.databind.ObjectMapper;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.List;
import java.util.Map;

public class Client {

    static final String KUBEMQ_URL = "http://localhost:9090";
    static final String AGENT_ID = "slow-agent-01";
    static final ObjectMapper MAPPER = new ObjectMapper();

    public static void main(String[] args) throws Exception {
        var payload = Map.of(
            "jsonrpc", "2.0",
            "id", 1,
            "method", "message/send",
            "params", Map.of(
                "message", Map.of("parts", List.of(Map.of("text", "This will timeout"))),
                "configuration", Map.of("timeout", 1)
            )
        );

        var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
        var req = HttpRequest.newBuilder()
            .uri(URI.create(KUBEMQ_URL + "/a2a/" + AGENT_ID))
            .header("Content-Type", "application/json")
            .timeout(Duration.ofSeconds(30))
            .POST(HttpRequest.BodyPublishers.ofString(MAPPER.writeValueAsString(payload)))
            .build();

        System.out.println("Sending request with timeout=1 to slow agent (5s delay)...");
        var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
        var data = MAPPER.readTree(resp.body());
        System.out.println(MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(data));

        var error = data.path("error");
        System.out.println("\nError code:    " + error.path("code").asInt());
        System.out.println("Error message: " + error.path("message").asText());

        assert error.path("code").asInt() == -32001 : "Expected -32001, got " + error.path("code").asInt();
        System.out.println("\nTimeout error (-32001) received as expected!");
    }
}
import asyncio
import json

import httpx

KUBEMQ_URL = "http://localhost:9090"
AGENT_ID = "slow-agent-01"


async def main() -> None:
    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "message/send",
        "params": {
            "message": {"parts": [{"text": "This will timeout"}]},
            "configuration": {"timeout": 1},
        },
    }

    async with httpx.AsyncClient(timeout=30) as client:
        print("Sending request with timeout=1 to slow agent (5s delay)...")
        resp = await client.post(f"{KUBEMQ_URL}/a2a/{AGENT_ID}", json=payload)
        data = resp.json()
        print(json.dumps(data, indent=2))

        error = data.get("error", {})
        print(f"\nError code:    {error.get('code')}")
        print(f"Error message: {error.get('message')}")

        assert error.get("code") == -32001, f"Expected -32001, got {error.get('code')}"
        print("\nTimeout error (-32001) received as expected!")


if __name__ == "__main__":
    asyncio.run(main())
const KUBEMQ_URL = "http://localhost:9090";
const AGENT_ID = "slow-agent-01";

async function main() {
  const request = {
    jsonrpc: "2.0",
    id: 1,
    method: "message/send",
    params: {
      message: { parts: [{ text: "This will timeout" }] },
      configuration: { timeout: 1 },
    },
  };

  console.log("Sending with timeout=1s to a 5s-delay agent...");

  const resp = await fetch(`${KUBEMQ_URL}/a2a/${AGENT_ID}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(request),
  });

  const data = await resp.json();
  console.log("Response:", JSON.stringify(data, null, 2));

  if (data.error) {
    console.log(`\nError code:    ${data.error.code} (expect -32001)`);
    console.log(`Error message: ${data.error.message}`);
    console.log(`Match:         ${data.error.code === -32001}`);
  } else {
    console.log("\nUnexpected: got success response instead of timeout");
  }
}

main().catch(console.error);

Was this page helpful?

On this page