[Bug]: `A2A-Version` sent as a request parameter is ignored (spec §3.6.1), so a v1.0 request is treated as 0.3
Maintainer thường phản hồi trong vòng 2 ngày
@rohityan đang làm issue này rồi.
Từ ngày 16/10/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
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
- Ngôn ngữ chính
- Python
- Star
- 2.2k
- Fork
- 511
- Merge trung bình
- 3 ngày 10 giờ
- Pull request đã merge (30 ngày)
- 47
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của a2aproject/a2a-python
-
[Bug]: REST task/request id sanitizationCó thể đã có người làm @Linux2010 đã nhận 112 ngày trước. Đang mởmaintainers-only
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
a2aproject/a2a-python#805 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[Bug]: Executor failure right after its Task is enqueued leaves the task SUBMITTED on DatabaseTaskStoreCó thể đã có người làm @rohityan đã nhận hôm nay. Đang mở
a2aproject/a2a-python#1351 · 2 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[Bug]: Closing one client from a ClientFactory closes the shared httpx client for every other clientCó thể đã có người làm @rohityan đã nhận 1 ngày trước. Đang mở
a2aproject/a2a-python#1349 · 2 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[Bug]: A2A exceptions lost their structured __repr__ after the client error refactor (#761)Có thể đã có người làm @rohityan đã nhận 1 ngày trước. Đang mở
a2aproject/a2a-python#1347 · 2 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[Bug]: Client transports reject responses with unrecognized fields (spec 5.7)Có thể đã có người làm @rohityan đã nhận 3 ngày trước. Đang mở
a2aproject/a2a-python#1341 · 1 bình luận · 2 người được giao ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của a2aproject/a2a-python
Issue tương tự
-
Custom provider API keys collide on one host: env slot keyed on host:port only, not URL pathĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
NousResearch/hermes-agent#140958 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Bisect issue233186Đang mởbisect
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
dtcxzyw/llvm-bisect-service#548 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
sallowayma-git/IELTS-practice#248 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 65/100
anthropics/claude-plugins-official#6763 · 10 bình luận · 10 reaction ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
Maintainer thường phản hồi trong vòng 1 ngày