[Bug]: `A2A-Version` sent as a request parameter is ignored (spec §3.6.1), so a v1.0 request is treated as 0.3
Los mantenedores suelen responder en 3 días
@Iwaniukooo11 ya está trabajando en esto.
Desde el 19/10/2026.
Evaluación
Este issue todavía no se ha evaluado.
Descripción
What happened?
Summary
The server only reads A2A-Version from the request header. A client that sends the version as a request parameter, which the specification allows, is treated as a 0.3 client and gets VersionNotSupportedError for a valid v1.0 request.
Section 3.6.1 ("Client Responsibilities") of the v1.0.0 specification says: "Clients MAY provide the A2A-Version as a request parameter instead of a header." Its example is GET /tasks/task-123?A2A-Version=1.0. Section 3.6.2 then requires the agent to process the request using the semantics of the requested version.
DefaultServerCallContextBuilder.build() copies only request.headers into state['headers'] (src/a2a/server/routes/common.py:115), and validate_version reads only that dict (src/a2a/utils/version_validator.py:68). The query string is never consulted, so the request falls through to the empty-header default of 0.3.
Reproduce
pip install "a2a-sdk[http-server]==1.2.2" httpx, then run:
import asyncio
import httpx
from starlette.applications import Starlette
from a2a.server.agent_execution import AgentExecutor
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.routes import create_jsonrpc_routes, create_rest_routes
from a2a.server.tasks import InMemoryTaskStore
from a2a.types import AgentCapabilities, AgentCard, AgentInterface
class Noop(AgentExecutor):
async def execute(self, context, event_queue): ...
async def cancel(self, context, event_queue): ...
card = AgentCard(
name="probe", description="probe", version="0.0.1",
capabilities=AgentCapabilities(),
supported_interfaces=[AgentInterface(
url="http://test/rpc", protocol_binding="JSONRPC", protocol_version="1.0")],
)
handler = DefaultRequestHandler(
agent_executor=Noop(), task_store=InMemoryTaskStore(), agent_card=card)
app = Starlette(routes=[*create_jsonrpc_routes(handler, "/rpc"),
*create_rest_routes(handler)])
RPC = {"jsonrpc": "2.0", "id": 1, "method": "GetTask", "params": {"id": "task-123"}}
HDR = {"A2A-Version": "1.0"}
async def main():
async with httpx.AsyncClient(transport=httpx.ASGITransport(app=app),
base_url="http://test") as c:
for label, resp in [
("JSON-RPC header ", await c.post("/rpc", json=RPC, headers=HDR)),
("JSON-RPC ?A2A-Version", await c.post("/rpc?A2A-Version=1.0", json=RPC)),
("HTTP+JSON header ", await c.get("/tasks/task-123", headers=HDR)),
("HTTP+JSON ?A2A-Version", await c.get("/tasks/task-123?A2A-Version=1.0")),
]:
body = resp.json()
err = body.get("error", body)
print(f"{label} -> HTTP {resp.status_code} {err.get('code')} {err.get('message')}")
asyncio.run(main())
Actual (identical on main at e86695c, and with enable_v0_3_compat=True):
JSON-RPC header -> HTTP 200 -32001 Task not found
JSON-RPC ?A2A-Version -> HTTP 200 -32009 A2A version '0.3' is not supported by this handler. Expected version '1.0'.
HTTP+JSON header -> HTTP 404 404 Task not found
HTTP+JSON ?A2A-Version -> HTTP 400 400 A2A version '0.3' is not supported by this handler. Expected version '1.0'.
Expected: the two ?A2A-Version=1.0 requests behave like the header requests and return Task not found.
On JSON-RPC the failure is quiet: an HTTP 200 carrying -32009. A client that checks the status code and then reads an SSE stream sees an empty stream, which looks like an agent with nothing to say.
Suggested fix
When the header is absent, fall back to the A2A-Version request parameter in DefaultServerCallContextBuilder.build(). That way every transport and validate_version see the same value. The spec does not say which wins when both are present; letting the header win seems the least surprising.
A smaller related improvement: when the client sent no version at all, say so in the error. Today the message reads "A2A version '0.3' is not supported", which suggests the client sent 0.3. Something like "no A2A-Version header or parameter; defaulted to 0.3, which this handler does not support" would point straight at the cause.
Relevant log output
Version mismatch: actual='0.3', expected='1.0'
Code of Conduct
- I agree to follow this project's Code of Conduct
- Lenguaje dominante
- Python
- Estrellas
- 2.2k
- Forks
- 518
- Merge medio
- 3 d 23 h
- PR fusionados (30 d)
- 41
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de a2aproject/a2a-python
-
[Bug]: `A2A-Version` validation ignores minor versions and the query parameterPosiblemente ocupada @rohityan la tomó hace 56 días. Abiertocomponent: server status:awaiting response
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
a2aproject/a2a-python#1204 · 3 comentarios · 1 asignado ·
Los mantenedores suelen responder en 3 días
-
[Bug]: REST task/request id sanitizationPosiblemente ocupada @Linux2010 la tomó hace 115 días. Abiertomaintainers-only
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
a2aproject/a2a-python#805 · 1 comentario ·
Los mantenedores suelen responder en 3 días
-
Legacy handler ignores history_length on message/streamPosiblemente ocupada @rohityan la tomó hoy. Abierto
a2aproject/a2a-python#1363 · 2 asignados ·
Los mantenedores suelen responder en 3 días
-
v0.3 client returns an empty status message and provider when they are unsetPosiblemente ocupada @rohityan la tomó hoy. Abierto
a2aproject/a2a-python#1361 · 2 asignados ·
Los mantenedores suelen responder en 3 días
-
[Bug]: VersionedDatabaseTaskStore get() and delete() fail with "no such table" when initialize() was not calledPosiblemente ocupada @rohityan la tomó hace 1 día. Abierto
a2aproject/a2a-python#1356 · 2 asignados ·
Los mantenedores suelen responder en 3 días
Todos los issues de a2aproject/a2a-python
Issues similares
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
anchore/grype-db#1149 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[Bug]: `hermes plugins update` clones an entire monorepo twice - `subdir` is resolved but dropped at both catalog-update call sitesPosiblemente ocupada @HootRock la tomó hoy. Abiertocomp/cli P2 type/perf
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
NousResearch/hermes-agent#142417 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
SMC SPEC
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
tenstorrent/tt-oca-harness#3287 ·
Los mantenedores suelen responder en 1 día
-
bug enhancement python
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
DewaldOosthuizen/tech-cheat-sheets-and-notes#392 ·
Los mantenedores suelen responder en 1 día
-
Critical advisories on mainAbiertosecurity
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
fabriziosalmi/wildbox#801 ·
Los mantenedores suelen responder en 1 día