UAT: A2A error codes use string constants instead of JSON-RPC 2.0 integer codes — wire format non-compliant with spec #3633

Open
opened 2026-04-05 20:59:47 +00:00 by freemo · 0 comments
Owner

Background and Context

Per docs/specification.md (lines 43394–43412), the A2A protocol mandates JSON-RPC 2.0 integer error codes. Standard protocol errors use the reserved range; application-specific errors use -32001 to -32099:

Error Code Meaning
-32700 Parse error
-32600 Invalid request
-32601 Method not found
-32602 Invalid params
-32603 Internal error
-32001 Entity not found
-32002 Authentication required
-32003 Authorization forbidden
-32004 Invalid state
-32005 Already exists
-32006 Budget exceeded
-32007 Version mismatch
-32008 Plan error

All errors must follow the JSON-RPC 2.0 error structure: { "code": <int>, "message": <string>, "data": <optional object> }. Clients are expected to dispatch on code (an integer) for precise error handling.

Current Behavior

src/cleveragents/a2a/errors.py defines error codes as string constants:

NOT_FOUND: str = "NOT_FOUND"
VALIDATION_ERROR: str = "VALIDATION_ERROR"
INVALID_STATE: str = "INVALID_STATE"
PLAN_ERROR: str = "PLAN_ERROR"
AUTH_ERROR: str = "AUTH_ERROR"
FORBIDDEN: str = "FORBIDDEN"
CONFIGURATION_ERROR: str = "CONFIGURATION_ERROR"
INTERNAL_ERROR: str = "INTERNAL_ERROR"

src/cleveragents/a2a/models.py line 69 types A2aErrorDetail.code as str:

class A2aErrorDetail(BaseModel):
    code: str  # WRONG: should be int per JSON-RPC 2.0
    message: str
    details: dict[str, Any] = {}

The map_domain_error() function in errors.py returns (str, str) tuples instead of (int, str).

Expected Behavior

  1. A2aErrorDetail.code must be typed as int
  2. Error constants must be integers matching the spec: NOT_FOUND = -32001, AUTH_ERROR = -32002, FORBIDDEN = -32003, INVALID_STATE = -32004, PLAN_ERROR = -32008, INTERNAL_ERROR = -32603, etc.
  3. map_domain_error() must return (int, str) tuples
  4. A2aOperationNotFoundError must map to -32601 (Method not found)
  5. A2aVersionMismatchError must map to -32007
  6. All callers of map_domain_error() and A2aErrorDetail must be updated to handle int codes

Acceptance Criteria

  • A2aErrorDetail.code is typed as int in models.py
  • All error constants in errors.py are integers matching the spec table above
  • map_domain_error() return type is tuple[int, str]
  • A2aOperationNotFoundError maps to -32601
  • A2aVersionMismatchError maps to -32007
  • No string error codes remain anywhere in the A2A error path
  • All existing Behave unit test scenarios for A2A error handling pass with integer codes
  • Pyright type checking passes with no suppressions (nox -e typecheck)
  • Coverage remains ≥97% (nox -e coverage_report)

Supporting Information

Steps to Reproduce:

from cleveragents.a2a.facade import A2aLocalFacade
from cleveragents.a2a.models import A2aRequest

facade = A2aLocalFacade()
response = facade.dispatch(A2aRequest(method="nonexistent/method", params={}))
# response.error.code == "NOT_FOUND"  (string — non-compliant)
# Expected: response.error.code == -32601  (integer per JSON-RPC 2.0)

response2 = facade.dispatch(A2aRequest(method="plan.execute", params={"plan_id": ""}))
# response2.error.code == "VALIDATION_ERROR"  (string — non-compliant)
# Expected: response2.error.code == -32602  (integer per JSON-RPC 2.0)

Impact: Any A2A client that dispatches on code for error handling (as the spec requires) will fail because it receives strings like "NOT_FOUND" instead of integers like -32001. This makes all A2A error responses non-compliant with JSON-RPC 2.0 and the specification.

Code Locations:

  • src/cleveragents/a2a/errors.py — error constants and map_domain_error()
  • src/cleveragents/a2a/models.pyA2aErrorDetail.code field type

Metadata

  • Branch: fix/v3.6-a2a-jsonrpc-integer-error-codes
  • Commit Message: fix(a2a): replace string error codes with JSON-RPC 2.0 integer codes
  • Milestone: v3.6.0
  • Parent Epic: #366

Subtasks

  • Change A2aErrorDetail.code type from str to int in src/cleveragents/a2a/models.py
  • Replace all string error constants in src/cleveragents/a2a/errors.py with the correct JSON-RPC 2.0 integer values per the spec table
  • Update map_domain_error() return type annotation to tuple[int, str] and update all return values to integer codes
  • Map A2aOperationNotFoundError-32601 (Method not found)
  • Map A2aVersionMismatchError-32007 (Version mismatch)
  • Update all callers of map_domain_error() and A2aErrorDetail to handle int codes
  • Tests (Behave): Update/add scenarios in features/ asserting error code values are integers matching the spec
  • Tests (Robot): Update/add integration test in robot/ verifying wire-format error codes are integers
  • Verify coverage ≥97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly (fix(a2a): replace string error codes with JSON-RPC 2.0 integer codes), followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly (fix/v3.6-a2a-jsonrpc-integer-error-codes).
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage ≥ 97%.

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Background and Context Per `docs/specification.md` (lines 43394–43412), the A2A protocol mandates **JSON-RPC 2.0 integer error codes**. Standard protocol errors use the reserved range; application-specific errors use `-32001` to `-32099`: | Error Code | Meaning | |---|---| | `-32700` | Parse error | | `-32600` | Invalid request | | `-32601` | Method not found | | `-32602` | Invalid params | | `-32603` | Internal error | | `-32001` | Entity not found | | `-32002` | Authentication required | | `-32003` | Authorization forbidden | | `-32004` | Invalid state | | `-32005` | Already exists | | `-32006` | Budget exceeded | | `-32007` | Version mismatch | | `-32008` | Plan error | All errors must follow the JSON-RPC 2.0 error structure: `{ "code": <int>, "message": <string>, "data": <optional object> }`. Clients are expected to dispatch on `code` (an integer) for precise error handling. ## Current Behavior `src/cleveragents/a2a/errors.py` defines error codes as **string constants**: ```python NOT_FOUND: str = "NOT_FOUND" VALIDATION_ERROR: str = "VALIDATION_ERROR" INVALID_STATE: str = "INVALID_STATE" PLAN_ERROR: str = "PLAN_ERROR" AUTH_ERROR: str = "AUTH_ERROR" FORBIDDEN: str = "FORBIDDEN" CONFIGURATION_ERROR: str = "CONFIGURATION_ERROR" INTERNAL_ERROR: str = "INTERNAL_ERROR" ``` `src/cleveragents/a2a/models.py` line 69 types `A2aErrorDetail.code` as `str`: ```python class A2aErrorDetail(BaseModel): code: str # WRONG: should be int per JSON-RPC 2.0 message: str details: dict[str, Any] = {} ``` The `map_domain_error()` function in `errors.py` returns `(str, str)` tuples instead of `(int, str)`. ## Expected Behavior 1. `A2aErrorDetail.code` must be typed as `int` 2. Error constants must be integers matching the spec: `NOT_FOUND = -32001`, `AUTH_ERROR = -32002`, `FORBIDDEN = -32003`, `INVALID_STATE = -32004`, `PLAN_ERROR = -32008`, `INTERNAL_ERROR = -32603`, etc. 3. `map_domain_error()` must return `(int, str)` tuples 4. `A2aOperationNotFoundError` must map to `-32601` (Method not found) 5. `A2aVersionMismatchError` must map to `-32007` 6. All callers of `map_domain_error()` and `A2aErrorDetail` must be updated to handle `int` codes ## Acceptance Criteria - [ ] `A2aErrorDetail.code` is typed as `int` in `models.py` - [ ] All error constants in `errors.py` are integers matching the spec table above - [ ] `map_domain_error()` return type is `tuple[int, str]` - [ ] `A2aOperationNotFoundError` maps to `-32601` - [ ] `A2aVersionMismatchError` maps to `-32007` - [ ] No string error codes remain anywhere in the A2A error path - [ ] All existing Behave unit test scenarios for A2A error handling pass with integer codes - [ ] Pyright type checking passes with no suppressions (`nox -e typecheck`) - [ ] Coverage remains ≥97% (`nox -e coverage_report`) ## Supporting Information **Steps to Reproduce:** ```python from cleveragents.a2a.facade import A2aLocalFacade from cleveragents.a2a.models import A2aRequest facade = A2aLocalFacade() response = facade.dispatch(A2aRequest(method="nonexistent/method", params={})) # response.error.code == "NOT_FOUND" (string — non-compliant) # Expected: response.error.code == -32601 (integer per JSON-RPC 2.0) response2 = facade.dispatch(A2aRequest(method="plan.execute", params={"plan_id": ""})) # response2.error.code == "VALIDATION_ERROR" (string — non-compliant) # Expected: response2.error.code == -32602 (integer per JSON-RPC 2.0) ``` **Impact:** Any A2A client that dispatches on `code` for error handling (as the spec requires) will fail because it receives strings like `"NOT_FOUND"` instead of integers like `-32001`. This makes all A2A error responses non-compliant with JSON-RPC 2.0 and the specification. **Code Locations:** - `src/cleveragents/a2a/errors.py` — error constants and `map_domain_error()` - `src/cleveragents/a2a/models.py` — `A2aErrorDetail.code` field type --- ## Metadata - **Branch**: `fix/v3.6-a2a-jsonrpc-integer-error-codes` - **Commit Message**: `fix(a2a): replace string error codes with JSON-RPC 2.0 integer codes` - **Milestone**: v3.6.0 - **Parent Epic**: #366 ## Subtasks - [ ] Change `A2aErrorDetail.code` type from `str` to `int` in `src/cleveragents/a2a/models.py` - [ ] Replace all string error constants in `src/cleveragents/a2a/errors.py` with the correct JSON-RPC 2.0 integer values per the spec table - [ ] Update `map_domain_error()` return type annotation to `tuple[int, str]` and update all return values to integer codes - [ ] Map `A2aOperationNotFoundError` → `-32601` (Method not found) - [ ] Map `A2aVersionMismatchError` → `-32007` (Version mismatch) - [ ] Update all callers of `map_domain_error()` and `A2aErrorDetail` to handle `int` codes - [ ] Tests (Behave): Update/add scenarios in `features/` asserting error `code` values are integers matching the spec - [ ] Tests (Robot): Update/add integration test in `robot/` verifying wire-format error codes are integers - [ ] Verify coverage ≥97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly (`fix(a2a): replace string error codes with JSON-RPC 2.0 integer codes`), followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly (`fix/v3.6-a2a-jsonrpc-integer-error-codes`). - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. - All nox stages pass. - Coverage ≥ 97%. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.6.0 milestone 2026-04-05 20:59:52 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#366 Epic: Post-MVP Deferred Work
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3633
No description provided.