a2aproject / a2aproject/a2a-python

[Bug]: grpc_handler maps 3 A2A errors to FAILED_PRECONDITION instead of UNIMPLEMENTED, and doesn't validate A2A-Version at all

Đang mở
#1,166 4 bình luận 0 reaction 1 người được giao Được @avilleroy51 nhận Xem trên GitHub
component: server status:awaiting response status:stale
Ngôn ngữ chính
Python
Star
2.1k
Fork
496
Merge trung bình
4 ngày 17 giờ
Pull request đã merge (30 ngày)
12

Mô tả

### What happened?

`grpc_handler.py`'s `_ERROR_CODE_MAP` (`src/a2a/server/request_handlers/grpc_handler.py:84-98`) maps 3 of the 9 A2A error types to the wrong gRPC status code, diverging from the canonical binding table in the spec (`specification.md` "Custom Binding Requirements" / error-code-mappings section):

| A2A Error Type | Spec gRPC Status | SDK gRPC Status |
|---|---|---|
| `PushNotificationNotSupportedError` | `UNIMPLEMENTED` | `FAILED_PRECONDITION` ❌ |
| `UnsupportedOperationError` | `UNIMPLEMENTED` | `FAILED_PRECONDITION` ❌ |
| `VersionNotSupportedError` | `UNIMPLEMENTED` | `FAILED_PRECONDITION` ❌ |

```python
_ERROR_CODE_MAP: dict[type[A2AError], grpc.StatusCode] = {
...
types.PushNotificationNotSupportedError: grpc.StatusCode.FAILED_PRECONDITION,
types.UnsupportedOperationError: grpc.StatusCode.FAILED_PRECONDITION,
...
types.VersionNotSupportedError: grpc.StatusCode.FAILED_PRECONDITION,
}
```

The other 6 mappings (`TaskNotFoundError`, `TaskNotCancelableError`, `ContentTypeNotSupportedError`, `InvalidAgentResponseError`, `ExtendedAgentCardNotConfiguredError`, `ExtensionSupportRequiredError`) are all correct against the same table.

### Second, related bug: gRPC transport doesn't validate `A2A-Version` at all

`jsonrpc_dispatcher.py` and `rest_dispatcher.py` both guard their handlers with `@validate_version(constants.PROTOCOL_VERSION_1_0)`, which raises `VersionNotSupportedError` for an unsupported `A2A-Version`. `grpc_handler.py` has no equivalent — a `SendMessage` gRPC call with metadata `a2a-version: 99.0` is processed normally instead of being rejected. Per spec (`specification.md:739`): "*Agents MUST process requests using the semantics of the requested `A2A-Version`... If the version is not supported by the interface, agents MUST return a `VersionNotSupportedError`.*"

### Reproduction

Against a standard `DefaultRequestHandlerV2`-backed gRPC server:

```python
import grpc
metadata = [("a2a-version", "99.0")]
client.stub.SendMessage(proto_request, metadata=metadata)
# succeeds — no VersionNotSupportedError, no version check at all
```

For the status-code mismatch, trigger any `PushNotificationNotSupportedError` (e.g. call `CreatePushNotificationConfig` when `capabilities.push_notifications` is `false`) over gRPC and inspect `e.code()` — it's `FAILED_PRECONDITION`, not `UNIMPLEMENTED`.

We hit both while running the official `a2a-tck` MUST-level gRPC suite against a reference SUT built on this SDK — `GRPC-ERR-002` fails on `test_push_not_supported_returns_unimplemented` and `test_version_not_supported_returns_unimplemented` for exactly these reasons.

### Expected

- Fix the 3 entries in `_ERROR_CODE_MAP` to `UNIMPLEMENTED`, matching the other 6 and the spec table.
- Apply the same version-validation the HTTP dispatchers already do to the gRPC transport (a `@validate_version`-equivalent, or an explicit check in `GrpcHandler` reading the `a2a-version` metadata key).

Happy to send a PR for both if useful.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.