fix(a2a): change A2aErrorDetail.code to int and map error constants to JSON-RPC 2.0 integer codes #3310
Labels
Clear labels
auto/needs-reevaluation
controller-managed
overdue
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Needs Feedback
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
Controller deferred this PR; awaiting Phase 6+ scope-evaluator or operator re-enablement.
Auto-agents controller manages this PR/issue (see tools/controller/deploy/RUNBOOK.md). Remove this label to abandon controller management.
PR blocked by an open issue dependency. Operator must close the dep (or remove the dependency link) before the merge driver can act. Auto-cleared by merge_drive when no open deps remain.
Most recent merge cycle hit CI timeout. Driver excludes this PR while last merge_cycle row is < 30 min old; label persists thereafter as visible history.
Currently being processed by an implementer worker.
Currently being processed by the merge driver.
Currently being processed by a reviewer worker.
Merge driver heartbeat stale; pipeline halted. Closed automatically on next clean tick.
Detected master commit violating the strict merge invariant. Tracked as an issue (not a PR label); kept here for label completeness.
In-cycle escalation: most recent attempt ran at the Tier 0 slot (`tier-0`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 1 slot (`tier-1`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 2 slot (`tier-2`). Slot's model defined in .opencode/models/tiers.yaml. Gated behind IMPLEMENTER_ESCALATION_TIER2_ENABLED.
In-cycle escalation: most recent attempt ran at the Tier -1 slot (`tier-min`). Slot's model defined in .opencode/models/tiers.yaml. Suffix is ``-min`` (not ``--1``) so the Forgejo UI reads naturally.
Tracking issues used by the AI Automation system for agents to communicate and report.
Rebase conflict needs LLM conflict-resolver.
Failing CI needs implementer attention.
Documenting a driver incident or rollback.
Reviewer has APPROVED this PR and no later REQUEST_CHANGES is outstanding. The merge driver requires this label to even consider a PR for merging. Set by the reviewer worker on APPROVE; cleared on REQUEST_CHANGES.
Train repeatedly lost master-tempo races. Driver excludes via merge_cycle until cooldown elapses; label persists as visible history.
Revert PR backing out an invariant violation. Fast-tracked through the merge driver.
Sentinel PR duplicated from upstream into a personal fork by tools/duplicate_prs_to_fork.py for pipeline testing. Lives only in the fork; the canonical pipeline never sees it.
No implementer activity for N days. Flagged for human review. Auto-cleared on next push to head branch.
Repeatedly fails on current master (>= 3 ci-fail-on-rebased-sha releases in 12 h). Excluded from driver until human triage.
A ticket in a blocked state and unable to complete until some other task is completed first.
Bounty
$100
A bounty of $100 for any open-source contributor who provides a MR that solves this issue
Bounty
$1000
A bounty of $1000 for any open-source contributor who provides a MR that solves this issue
Bounty
$10000
A bounty of $10000 for any open-source contributor who provides a MR that solves this issue
Bounty
$20
A bounty of $20 for any open-source contributor who provides a MR that solves this issue
Bounty
$2000
A bounty of $2000 for any open-source contributor who provides a MR that solves this issue
Bounty
$250
A bounty of $250 for any open-source contributor who provides a MR that solves this issue
Bounty
$50
A bounty of $50 for any open-source contributor who provides a MR that solves this issue
Bounty
$500
A bounty of $500 for any open-source contributor who provides a MR that solves this issue
Bounty
$5000
A bounty of $5000 for any open-source contributor who provides a MR that solves this issue
Bounty
$750
A bounty of $750 for any open-source contributor who provides a MR that solves this issue
MoSCoW
Could have
Could have feature in order to satisfy the epic/legendary.
MoSCoW
Must have
Must have feature in order to satisfy the epic/legendary.
MoSCoW
Should have
Should have feature in order to satisfy the epic/legendary.
There are questions in the ticket that can not be completed until the project owner provides clarity.
Points
1
1 man-hours worth of work for an expert with no learning curve.
Points
13
13 man-hours worth of work for an expert with no learning curve.
Points
2
2 man-hours worth of work for an expert with no learning curve.
Points
21
21 man-hours worth of work for an expert with no learning curve.
Points
3
3 man-hours worth of work for an expert with no learning curve.
Points
34
34 man-hours worth of work for an expert with no learning curve.
Points
5
5 man-hours worth of work for an expert with no learning curve.
Points
55
55 man-hours worth of work for an expert with no learning curve.
Points
8
8 man-hours worth of work for an expert with no learning curve.
Points
88
88 man-hours worth of work for an expert with no learning curve.
Priority
Backlog
This ticket has backlogged priority and is not to be worked on yet
Priority
CI Blocker
Critical priority issue that blocks CI/CD pipeline and prevents PR merges
Priority
Critical
The priority is critical
Priority
High
The priority is high
Priority
Low
The priority is low
Priority
Medium
The priority is medium
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
A ticket for learning a tool or technology that is needed to be able to do future planning and design.
State
Completed
The ticket has been fully implemented, completed, and merged with the source code. This label should only be applied once a ticket is closed.
State
Duplicate
A ticket that represents the same content as an existing ticket.
State
In Progress
A ticket that is actively being developed.
State
In Review
A ticket that has had some code completed to implement but is waiting to pass peer review and is not yet merged in.
State
Paused
This ticket's work started but wasn't finished. It's on hold (likely in a feature branch) and will be resumed later, either due to a blocker or a delay.
State
Unverified
All new tickets start in this state. A developer may set it to show the ticket is unverified. This means we haven't agreed to work on it. It will either move to a verified state or be closed as wontdo.
State
Verified
The issue has been verified by a developer as legitimate. It will be worked on and verified tickets are now considered part of the backlog.
State
Wont Do
This ticket has been decided it wont be done. This may mean the bug has been determined to not be real (cant verify) or the feature is one we have decided we dont want to adopt.
Type
Automation
Any edits or discussion about the AI automated coding system.
Type
Bug
Something that doesnt work as intended.
Type
Discussion
Anytime a ticket represents a discussion about a subject and doesnt fall into one of the other categories.
Type
Documentation
An error or improvement needed in the documentation.
Type
Epic
Any first tier epic. That is, an epic which contains only issues as children and will not have sub-epics.
Type
Feature
Some new functionality not present.
Type
Legendary
A type of Epic which will contain other Epics.
Type
Refactor
A code change that restructures existing code without changing its external behavior.
Type
Support
Someone needs help using the project.
Type
Task
A generic task that doesnt fit into the other type categories.
Type
Testing
Work exclusively focusing on fixing or expanding testing.
No Label
Projects
Clear projects
No project
Assignees
aditya (Aditya Chhabra)
aleenaumair (Aleena Umair)
brent.edwards (Brent Edwards)
CoreRasurae (Luis Mendes)
drew (Drew Morris)
eugen.thaci (Eugen Thaci)
freemo (Jeffrey Phillips Freeman)
HAL9000 (HAL 9000)
HAL9001 (HAL9001)
hamza.khyari (Hamza Khyari)
hurui200320 (Rui Hu)
justin.morris
khird (Kyle Hird)
org.cleveragents
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Blocks
Reference: cleveragents/cleveragents-core#3310
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "fix/a2a-error-codes-integer-jsonrpc2"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Fixes #2746 —
A2aErrorDetail.codewas typed asstrand error constants were string literals, violating the JSON-RPC 2.0 specification which requires error codes to be integers.Problem
External A2A-compliant clients received
{"code": "NOT_FOUND", ...}instead of the required{"code": -32001, ...}, breaking interoperability with any standards-conformant JSON-RPC 2.0 client.Changes
Core Type Fix
src/cleveragents/a2a/models.py: ChangedA2aErrorDetail.codefromstrtoint; updatedfield_validatorto only validatemessagefield (Pydantic enforces int type forcode)src/cleveragents/a2a/errors.py: Changed all error code constants from string literals to JSON-RPC 2.0 integer codes perdocs/reference/a2a.mdtaxonomy:NOT_FOUND = -32001AUTH_ERROR = -32002FORBIDDEN = -32003INVALID_STATE = -32004PLAN_ERROR = -32008CONFIGURATION_ERROR = -32009VALIDATION_ERROR = -32602INTERNAL_ERROR = -32603map_domain_error()return type fromtuple[str, str]totuple[int, str]Test Updates
features/steps/a2a_facade_steps.py: UpdatedA2aErrorDetailconstruction to map symbolic string names to integer codes via_CODE_MAPfeatures/steps/a2a_facade_wiring_steps.py: Updated error code assertion to map symbolic names to integers for comparisonfeatures/steps/a2a_facade_coverage_boost_steps.py: Same as abovefeatures/steps/a2a_jsonrpc_wire_format_steps.py: Updated allA2aErrorDetailconstructions and JSON-RPC dict payloads to use integer codesrobot/helper_a2a_facade_wiring.py: Updatedwired_error_mapping()to compare against integer codesrobot/helper_a2a_jsonrpc_wire_format.py: Updatedresponse_error_wire_format()to use integer code-32001instead of string"NOT_FOUND"Design Decisions
Backward-compatible step definitions: Feature files continue to use symbolic names like
"NOT_FOUND"in Gherkin scenarios. Step definitions map these to integer codes via_CODE_MAP, avoiding mass feature file changes while maintaining readability.Integer taxonomy follows spec: The integer values follow the JSON-RPC 2.0 standard codes (-32700 to -32600) for standard errors, and the application-defined range (-32001 to -32009) for domain-specific errors as documented in
docs/reference/a2a.md.CONFIGURATION_ERRORassigned -32009: Not in the standard JSON-RPC 2.0 range but follows the application-defined pattern from the spec taxonomy.Quality Gates
nox -e typecheck: ✅ 0 errors, 0 warningsCloses #2746
Automated by CleverAgents Bot
Supervisor: Implementation | Agent: ca-issue-worker
🔒 Review claimed by reviewer-pool-1 [claim-token: reviewer-pool-1-3310-1775375100]
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: ca-continuous-pr-reviewer
🔍 Code Review — REQUEST CHANGES
Reviewed PR #3310 with focus on test-coverage-quality, test-scenario-completeness, and test-maintainability.
The core change — converting
A2aErrorDetail.codefromstrtointand mapping error constants to JSON-RPC 2.0 integer codes — is correct and well-motivated. The JSON-RPC 2.0 specification (Section 5.1) requires error codes to be integers, and this fix brings the implementation into compliance. The integer values chosen align with the taxonomy documented indocs/reference/a2a.md.However, I found issues in test maintainability and spec alignment that should be addressed before merge.
Required Changes
1. [TEST-MAINTAINABILITY]
_CODE_MAPduplicated 6 times across 4 step filesLocations:
features/steps/a2a_facade_steps.py— defined twice (instep_create_responseandstep_create_error_detail)features/steps/a2a_facade_wiring_steps.py— defined once (instep_wired_error_code)features/steps/a2a_facade_coverage_boost_steps.py— defined once (instep_cb_error_code)features/steps/a2a_jsonrpc_wire_format_steps.py— defined twice (instep_create_error_responseandstep_jsonrpc_error_response_dict)Issue: The identical
_CODE_MAPdictionary mapping symbolic error names to integer codes is copy-pasted 6 times. If a new error code is added (e.g.,-32005forDuplicateEntityError, which is already in the spec but not in the constants), or an existing code value changes, all 6 copies must be updated in lockstep. This is a high-risk maintenance burden and violates DRY principles.Required: Extract
_CODE_MAPto a single shared location. Options:features/steps/_a2a_test_helpers.py)cleveragents.a2a.errorsmodule constants, e.g.:Then import and use this single definition in all step files.
2. [SPEC]
CONFIGURATION_ERROR = -32009not documented indocs/reference/a2a.mdsrc/cleveragents/a2a/errors.py—CONFIGURATION_ERROR: int = -32009docs/reference/a2a.mdonly goes up to-32008(PlanError). The code-32009forConfigurationErroris not listed in the spec reference. This creates a discrepancy between the code and the specification — which per project rules is the source of truth.-32009 | ConfigurationError | Configuration errorto the Error Code Taxonomy table indocs/reference/a2a.md, ORNon-blocking Suggestions
3. [TEST-COVERAGE] Missing test coverage for
AuthenticationError,AuthorizationError, andConfigurationErrormappingsThe
wired_error_mapping()function inrobot/helper_a2a_facade_wiring.pytests the mapping forResourceNotFoundError,ValidationError,PlanError, andBusinessRuleViolation, but does not testAuthenticationError → AUTH_ERROR (-32002),AuthorizationError → FORBIDDEN (-32003), orConfigurationError → CONFIGURATION_ERROR (-32009). Similarly, the Behave wiring steps only exercise NOT_FOUND, VALIDATION_ERROR, PLAN_ERROR, and INVALID_STATE error paths. Consider adding scenarios for the remaining mappings to ensure complete coverage of themap_domain_error()function.4. [TEST-QUALITY] Silent fallback in
_CODE_MAP.get()could mask test bugsIn several step definitions, the fallback
_CODE_MAP.get(code, _a2a_errors.INTERNAL_ERROR)silently maps any unknown symbolic name toINTERNAL_ERROR. If a feature file has a typo (e.g.,"NOTFOUND"instead of"NOT_FOUND"), the test would silently use-32603instead of failing. Consider using a strict lookup that raisesKeyErrorfor unknown names, or at minimum logging a warning.5. [TEST-QUALITY] Pre-existing
# type: ignorecomments in test filesfeatures/steps/a2a_facade_wiring_steps.pyandfeatures/steps/a2a_jsonrpc_wire_format_steps.pycontain# type: ignore[assignment,misc]in theirImportErrorfallback blocks. Per CONTRIBUTING.md,# type: ignoresuppressions are forbidden. These are pre-existing (not introduced by this PR), but worth noting for a follow-up cleanup.Good Aspects
"NOT_FOUND") while step definitions handle the mapping — excellent for test readabilitycodefrom thefield_validatoris correct since Pydantic enforcesinttype nativelyDecision: REQUEST CHANGES 🔄
The two required changes (extracting duplicated
_CODE_MAPand documenting-32009in the spec) should be addressed before merge. The core implementation is sound.Automated by CleverAgents Bot
Supervisor: PR Review | Agent: ca-pr-self-reviewer
🔍 Code Review — Architecture, Module Boundaries & Interface Contracts
Reviewed PR #3310 with focus on architecture-alignment, module-boundaries, and interface-contracts.
Overview
This PR correctly fixes a JSON-RPC 2.0 specification compliance defect:
A2aErrorDetail.codewas typed asstrwith string literal constants, but the JSON-RPC 2.0 specification (Section 5.1) mandates integer error codes. The fix changes the type tointand maps all error constants to their proper integer values from thedocs/reference/a2a.mdtaxonomy.The core implementation is sound. I'm adding architecture-focused observations that complement the previous review's test-quality findings.
Architecture Alignment
1. ✅ JSON-RPC 2.0 Wire Format Compliance — Correct
The integer code assignments align with the spec taxonomy in
docs/reference/a2a.md:NOT_FOUND-32001AUTH_ERROR-32002FORBIDDEN-32003INVALID_STATE-32004PLAN_ERROR-32008VALIDATION_ERROR-32602INTERNAL_ERROR-32603CONFIGURATION_ERROR-320092. ⚠️ [SPEC GAP]
CONFIGURATION_ERROR = -32009— Not indocs/reference/a2a.mdsrc/cleveragents/a2a/errors.py:44docs/reference/a2a.mdends at-32008(PlanError). The code-32009forConfigurationErroris not listed. The code's own comment block (lines 26-39) documents it, but the authoritative spec reference does not.docs/reference/a2a.mdError Code Taxonomy table to include| -32009 | ConfigurationError | Configuration error |, or file a follow-up issue to track the spec update.3. ⚠️ [SPEC GAP] Missing error code constants for spec-defined codes
The spec defines three additional error codes that have no corresponding constants in
errors.py:-32005→DuplicateEntityError-32006→BudgetExceededError-32007→A2aVersionMismatchErrorThese are not blocking for this PR (which is scoped to fixing the str→int type), but they represent an incomplete mapping between the spec taxonomy and the code. Consider filing a follow-up issue.
Interface Contracts
4. ✅
map_domain_error()return type correctly updatedtuple[str, str]tuple[int, str]This is a breaking change to the public API, but it's the correct fix. The function is exported in
__all__and its docstring is properly updated to document the new integer return type. All callers within the codebase are updated.5. ✅
A2aErrorDetail.codetype change — Correct Pydantic approachcode: strwith@field_validator("code", "message")checking non-emptycode: intwith@field_validator("message")onlyRemoving
codefrom the field validator is correct — Pydantic v2 enforces theinttype annotation natively, so the non-empty string check is no longer applicable. Themodel_config = ConfigDict(strict=False)allows coercion from compatible types (e.g.,float→int), which is appropriate for JSON deserialization.6. ℹ️ [DOCSTRING]
A2aErrorDetaildocstring is slightly misleadingsrc/cleveragents/a2a/models.py,A2aErrorDetailclass docstringModule Boundaries
7. ⚠️ [DRY]
_CODE_MAPduplicated across module boundariesLocations: 6 definitions across 4 step files:
features/steps/a2a_facade_steps.py(×2:step_create_response,step_create_error_detail)features/steps/a2a_facade_wiring_steps.py(×1:step_wired_error_code)features/steps/a2a_facade_coverage_boost_steps.py(×1:step_cb_error_code)features/steps/a2a_jsonrpc_wire_format_steps.py(×2:step_create_error_response,step_jsonrpc_error_response_dict)Issue: This creates a coupling problem: the mapping between symbolic names and integer codes is now a de facto interface contract between the feature files and the step definitions, but it's defined 6 times with no single source of truth. If a code value changes or a new code is added, all 6 copies must be updated in lockstep.
Architectural recommendation: Extract to a shared test helper that derives the mapping programmatically from
cleveragents.a2a.errors:This ensures the test mapping always stays in sync with the source module.
8. ✅ Robot Framework helpers correctly updated
Both
robot/helper_a2a_facade_wiring.pyandrobot/helper_a2a_jsonrpc_wire_format.pyare properly updated:wired_error_mapping()now compares against integer codes from the errors moduleresponse_error_wire_format()uses-32001directly instead of"NOT_FOUND"The Robot helpers import from
cleveragents.a2a.errorsdirectly rather than duplicating the mapping, which is the correct pattern.CONTRIBUTING.md Compliance
fix(a2a): change A2aErrorDetail.code to int...ISSUES CLOSED: #2746footerCloses #2746Type/Buglabel# type: ignoreintroducedPre-existing Issues (Not Introduced by This PR)
features/steps/a2a_facade_wiring_steps.pylines 20-22:# type: ignore[assignment,misc]in ImportError fallbackfeatures/steps/a2a_jsonrpc_wire_format_steps.pylines 24-27:# type: ignore[assignment,misc]in ImportError fallbackfeatures/steps/a2a_facade_coverage_boost_steps.pyline 82:# type: ignore[arg-type](intentional for testing TypeError path)These violate CONTRIBUTING.md but are pre-existing. Consider a follow-up cleanup issue.
Summary
The core implementation is architecturally sound — it correctly aligns the A2A error code interface with JSON-RPC 2.0 requirements. The interface contract changes (
str→int) are properly propagated through all layers (models, error constants, domain mapping, unit tests, integration tests).Items requiring attention before merge:
-32009— Updatedocs/reference/a2a.mdor file follow-up issue_CODE_MAPduplication — Extract to shared test helper to maintain module boundary hygieneNon-blocking suggestions:
3. Clarify
A2aErrorDetaildocstring re: implementation-defined vs application-defined codes4. Consider follow-up issue for missing spec codes (-32005, -32006, -32007)
5. Consider follow-up issue for pre-existing
# type: ignorein test step filesAutomated by CleverAgents Bot
Reviewer: Code Quality | Agent: ca-pr-self-reviewer
538158526ctof5d244cd37Review Feedback Addressed
Both required changes from the REQUEST CHANGES review have been implemented and pushed (amended commit
f5d244cd).Required Change 1:
_CODE_MAPduplication → shared module ✅Extracted to
features/steps/_a2a_code_map.py— a new shared module that derives the mapping directly fromcleveragents.a2a.errorsconstants:All 4 step files now import
A2A_CODE_MAPfrom this single source of truth:features/steps/a2a_facade_steps.py— 2 inline_CODE_MAPdicts removedfeatures/steps/a2a_facade_wiring_steps.py— 1 inline_CODE_MAPdict removedfeatures/steps/a2a_facade_coverage_boost_steps.py— 1 inline_CODE_MAPdict removedfeatures/steps/a2a_jsonrpc_wire_format_steps.py— 2 inline_CODE_MAPdicts removedTotal: 6 duplicate definitions → 1 canonical definition.
Required Change 2:
CONFIGURATION_ERROR = -32009documented in spec ✅Added to the Error Code Taxonomy table in
docs/reference/a2a.md:The table now covers all 8 error constants defined in
errors.py.All files pass Ruff linting with zero violations.
Automated by CleverAgents Bot
Supervisor: Implementation | Agent: ca-issue-worker
🔍 Code Review — APPROVED ✅
Reviewed PR #3310 with focus on api-consistency, naming-conventions, and code-patterns.
This PR fixes a JSON-RPC 2.0 specification compliance defect where
A2aErrorDetail.codewas typed asstrwith string literal constants, but the JSON-RPC 2.0 specification (Section 5.1) mandates integer error codes. The fix correctly changes the type tointand maps all error constants to their proper integer values per thedocs/reference/a2a.mdtaxonomy.I note that a previous review (now stale) requested two changes — extracting duplicated
_CODE_MAPto a shared module and documenting-32009in the spec — and both have been addressed in the amended commit.Deep Dive: API Consistency ✅
A2aErrorDetail.code: int— Correctly matches JSON-RPC 2.0 Section 5.1 requirement. Themodel_config = ConfigDict(strict=False)appropriately allows coercion from compatible types during JSON deserialization.map_domain_error()return type — Properly updated fromtuple[str, str]totuple[int, str]. The docstring is updated to document the new integer return type. All callers are updated consistently.__all__exports — Botherrors.pyandmodels.pyhave complete__all__lists covering all public symbols. The 8 error code constants, 4 exception classes, andmap_domain_errorare all exported.docs/reference/a2a.mdError Code Taxonomy table (which now includes-32009forConfigurationError).("code", "message")to("message")only, since Pydantic v2 enforces theinttype annotation natively. The non-empty string check is no longer applicable to an integer field.Deep Dive: Naming Conventions ✅
UPPER_SNAKE_CASEconsistently:NOT_FOUND,AUTH_ERROR,FORBIDDEN,INVALID_STATE,PLAN_ERROR,CONFIGURATION_ERROR,VALIDATION_ERROR,INTERNAL_ERROR.PascalCasewithA2aprefix:A2aError,A2aNotAvailableError,A2aVersionMismatchError,A2aOperationNotFoundError. Consistent with project conventions._a2a_code_map.pyuses underscore prefix appropriately for an internal module. The constantA2A_CODE_MAPusesUPPER_SNAKE_CASEcorrectly for a module-level constant.int), all function signatures are fully typed, and return types are specified.Deep Dive: Code Patterns ✅
features/steps/_a2a_code_map.pyderives values directly fromcleveragents.a2a.errorsconstants rather than hardcoding integers. This ensures the test mapping stays in sync with the source module automatically. Excellent pattern.A2A_CODE_MAP.get(code, int(code) if code.lstrip("-").isdigit() else _a2a_errors.INTERNAL_ERROR)handles both symbolic names from Gherkin and raw integer strings gracefully. Consistent across all step files.map_domain_error()precedence chain — The isinstance chain correctly checks specific exception types before their base classes (e.g.,PlanErrorbeforeBusinessRuleViolation,CleverAgentsErroras final catch-all). This prevents incorrect classification."NOT_FOUND") while step definitions handle the mapping. This preserves test readability without coupling feature files to implementation details.Standard Criteria
fix(a2a): change A2aErrorDetail.code to int...ISSUES CLOSED: #2746footerCloses #2746Type/Buglabel# type: ignoreintroduceddocs/reference/a2a.mdupdated with-32009Minor Suggestions (Non-blocking)
Duplicate
A2aResponseconstruction infeatures/steps/a2a_jsonrpc_wire_format_steps.py— Instep_create_error_response(),context.responseis assigned twice with identical values:The second assignment overwrites the first with the same value. This is harmless but appears to be a copy-paste artifact. Consider removing the duplicate.
A2aErrorDetaildocstring precision — The docstring states "Application-defined codes must be outside this range" (referring to -32768 to -32000), but the codes used (-32001 to -32009) are within this range as "implementation-defined server errors" per JSON-RPC 2.0. This is technically correct usage but the docstring wording could be more precise. Non-blocking.Missing error code constants for spec-defined codes — The spec defines
-32005(DuplicateEntityError),-32006(BudgetExceededError), and-32007(A2aVersionMismatchError) but these don't have corresponding constants inerrors.py. This is a pre-existing gap outside the scope of this PR, but worth a follow-up issue.Pre-existing
# type: ignorein test files —a2a_facade_wiring_steps.pyanda2a_jsonrpc_wire_format_steps.pycontain# type: ignore[assignment,misc]in theirImportErrorfallback blocks. These are pre-existing (not introduced by this PR) but violate CONTRIBUTING.md. Worth a follow-up cleanup.Decision: APPROVED ✅
The implementation is correct, the API changes are consistent, naming follows project conventions, and code patterns are clean. The previous review's required changes have been properly addressed. The core
str→inttype change is well-propagated through all layers (models, error constants, domain mapping, unit tests, integration tests, spec documentation).Automated by CleverAgents Bot
Supervisor: PR Review | Agent: ca-pr-self-reviewer