diff --git a/features/steps/server_lifecycle_steps.py b/features/steps/server_lifecycle_steps.py index 2332051c5..6418f129d 100644 --- a/features/steps/server_lifecycle_steps.py +++ b/features/steps/server_lifecycle_steps.py @@ -132,8 +132,11 @@ def step_post_a2a(context: Any, operation: str) -> None: @when("I POST a malformed JSON body to /a2a") def step_post_a2a_malformed(context: Any) -> None: - # Send a body that cannot be parsed into A2aRequest (missing operation) - context.response = context.test_client.post("/a2a", json={"bad": "data"}) + context.response = context.test_client.post( + "/a2a", + content=b"not-valid-json", + headers={"Content-Type": "application/json"}, + ) @then("the response status code should be {code:d}") diff --git a/src/cleveragents/infrastructure/server/asgi_app.py b/src/cleveragents/infrastructure/server/asgi_app.py index 3471c868d..3d0718367 100644 --- a/src/cleveragents/infrastructure/server/asgi_app.py +++ b/src/cleveragents/infrastructure/server/asgi_app.py @@ -13,6 +13,7 @@ at ``/.well-known/agent.json`` per the A2A specification. from __future__ import annotations +import json from typing import Any import structlog @@ -120,7 +121,20 @@ def create_asgi_app( schema, dispatches it through the facade, and returns the :class:`A2aResponse` envelope. """ - body: dict[str, Any] = await request.json() + try: + body: dict[str, Any] = await request.json() + except json.JSONDecodeError as exc: + logger.warning("a2a.server.parse_error", error=str(exc)) + return JSONResponse( + status_code=400, + content={ + "jsonrpc": "2.0", + "error": { + "code": -32700, + "message": "Parse error: request body is not valid JSON", + }, + }, + ) # Accept "operation" as an alias for "method" (proprietary wire format). if "method" not in body and "operation" in body: