Skip to main content
Version: v1.1.0

Errors

Anatomy of a typed AAP error inside the JSON-RPC error envelope: error.code, data.code, retryable

AAP defines a single typed error payload (aap.error) that every dealer agent MUST use when a skill cannot be fulfilled. The error rides inside the standard A2A error envelope: error.data of the JSON-RPC error response (Section 9.5). AAP v1.1 uses a single transport — JSON-RPC 2.0; the HTTP+JSON (REST) binding was removed in v1.1.

Error payload shape

{
"type": "aap.error",
"error_id": "err_01HZ9EXAMPLE",
"code": "SCHEMA_VALIDATION_FAILED",
"message": "request failed validation with 2 errors",
"retryable": false,
"details": {
"errors": [
{ "instanceLocation": "/filters/year_min", "keyword": "type", "error": "must be an integer" },
{ "instanceLocation": "/filters/make", "keyword": "additionalProperties", "error": "unknown filter key" }
]
},
"created_at": "2026-04-30T10:15:30Z"
}
FieldTypeRequiredDescription
typeconstyesAlways aap.error.
error_idstringyesUnique identifier for this error instance (UUID recommended), suitable for support correlation.
codeenumyesOne of the 12 AAP error codes below.
messagestringyesHuman-readable summary. May be surfaced to the end user.
retryablebooleanyesWhether the buyer agent SHOULD retry the same request after a backoff.
detailsobjectnoCode-specific details. For validation errors it carries an errors[] array listing EVERY problem at once (see below); other codes use it for retry hints, ids, etc.
created_atdate-timeyesWhen the error was generated by the dealer agent.

details.errors[] — all problems at once

Validation errors (SCHEMA_VALIDATION_FAILED, MISSING_REQUIRED_FIELD, INVALID_CONDITION) put every failing field in a single details.errors array so a buyer agent fixes the whole payload in one pass instead of one round-trip per error. Each entry follows the JSON-Schema-2020-12 standard output unit shape:

FieldTypeDescription
instanceLocationstringJSON Pointer to the failing field (e.g. /consent/scope/0).
keywordstringThe violated constraint (type, required, additionalProperties, enum, …).
errorstringHuman-readable message for that field.

A dealer agent MUST return all currently-detectable validation errors in one response — never just the first.

Error code reference

The 12 codes, their meaning, recommended JSON-RPC code, and retryable default.

codeMeaningJSON-RPCretryable default
UNSUPPORTED_SKILLThe agent does not implement this skill.-32601 (Method not found)false
SCHEMA_VALIDATION_FAILEDRequest body fails JSON Schema validation.-32602 (Invalid params)false
MISSING_REQUIRED_FIELDA specifically required field is absent.-32602 (Invalid params)false
INVALID_CONDITIONvehicle_of_interest.condition is in the trade-in vocabulary, or trade_in.condition is in the sale-condition vocabulary.-32602 (Invalid params)false
VEHICLE_NOT_FOUNDThe supplied vin / stock / vehicle_id does not match any listing.-32000 (Server error)false
VEHICLE_UNAVAILABLEThe vehicle exists but its status is no longer one of available | intransit | pending.-32000 (Server error)false
CONTACT_CONSENT_REQUIREDcustomer info present without consent, or follow-up channel not in consent.allowed_channels.-32000 (Server error)false
INVALID_CONSENTconsent is present but malformed, expired, or its scope does not cover the called skill.-32000 (Server error)false
APPOINTMENT_TIME_UNAVAILABLEThe requested appointment_at cannot be honored AND the dealer has no proposed alternatives.-32000 (Server error)false
IDEMPOTENCY_CONFLICTAn idempotency_key was reused with a different request payload.-32000 (Server error)false
RATE_LIMITEDClient has exceeded the dealer's rate limit.-32002 (Server error reserved)true
INTERNAL_ERRORUnhandled dealer-side error.-32603 (Internal error)true

retryable is a default, not a hard rule. Dealer agents MAY override it per-instance — for example, a SCHEMA_VALIDATION_FAILED is conceptually non-retryable (the request is malformed and a retry will fail identically), but a transient INTERNAL_ERROR is conceptually retryable. Buyer agents MUST honor the value the dealer returns rather than the table default.

Per-code semantics

UNSUPPORTED_SKILL

Returned when a buyer agent calls a skill id the dealer agent does not implement. AAP v1.1 agents declare the subset of the five skills they implement (at least one) on their agent card, so buyer agents SHOULD check the declared skills before calling. This code also covers forward-compat scenarios where future AAP versions add skills not present in v1.1.

SCHEMA_VALIDATION_FAILED

Returned when the request body does not satisfy the AAP request schema (missing type, wrong field types, unknown filter keys, unknown enum values, etc.). details.errors[] MUST list all failing fields at once — each with its instanceLocation, keyword, and error — so the buyer agent can correct the entire payload in a single retry.

MISSING_REQUIRED_FIELD

Returned when a specifically required field is absent. This overlaps with SCHEMA_VALIDATION_FAILED; dealer agents MAY use either, but MISSING_REQUIRED_FIELD is preferred when the issue is a single missing required field rather than a structural validation problem (e.g. a lead.submit request whose appointment.appointment_type is test_drive but no vehicle_of_interest is provided).

INVALID_CONDITION

Returned when the condition value is set to an item from the wrong vocabulary for its context: vehicle_of_interest.condition MUST be one of new | used | cpo, and trade_in.condition MUST be one of excellent | good | fair | poor. The base Vehicle schema accepts the union of both vocabularies because the same shape is used in inventory results too; lead.submit enforces the per-context subset and rejects with INVALID_CONDITION when violated.

VEHICLE_NOT_FOUND

Returned by inventory.vehicle (or by lead.submit when vehicle_of_interest does not match) when none of the supplied identifiers (vin, stock, vehicle_id, year+make+model) match a listing.

VEHICLE_UNAVAILABLE

Returned when the listing existed but is no longer available — e.g. its status moved out of the available | intransit | pending set between an inventory.search snapshot and a follow-up inventory.vehicle call. Buyer agents SHOULD recompute search results and surface the change to the user.

Returned when a lead.submit request omits consent, or when the consent.allowed_channels[] does not include the channel the dealer's process needs to use for follow-up. See Behavior rules.

Returned when consent is structurally present but unusable: e.g. consent.scope[] is not exactly ["lead_submission"], or consent.granted_at is in the future, or consent_text is empty.

APPOINTMENT_TIME_UNAVAILABLE

Returned by lead.submit when an appointment block was included, the requested appointment_at cannot be honored, AND the dealer has no proposed_times to offer. Dealers SHOULD prefer data.appointment.status: "proposed" with alternative times over this error whenever possible. The lead itself MAY still be received even when the appointment portion fails.

IDEMPOTENCY_CONFLICT

Returned by lead.submit when an idempotency_key is reused with a request payload that differs from the original submission. A retry with the same key AND the same payload MUST be treated as idempotent — the dealer returns the original lead (e.g. data.status: "duplicate"), not this error. retryable: false: the buyer agent must use a fresh idempotency_key for a genuinely new request.

RATE_LIMITED

Returned when the buyer agent exceeds the dealer's per-key quota. retryable: true is the default. Dealer agents SHOULD include details.retry_after_ms (or details.retry_after_seconds) so the buyer agent can back off appropriately. AAP does not standardize the rate-limit values themselves.

INTERNAL_ERROR

A catch-all for unexpected dealer-side failures. retryable: true is the default; the buyer agent SHOULD retry with exponential backoff. Dealer agents SHOULD set error_id so support tickets can correlate to logs.

Example error payloads

JSON-RPC error response

{
"jsonrpc": "2.0",
"id": "req-3",
"error": {
"code": -32602,
"message": "Invalid params: filters.year_min must be an integer",
"data": {
"type": "aap.error",
"error_id": "err_01HZ9EXAMPLE",
"code": "SCHEMA_VALIDATION_FAILED",
"message": "request failed validation with 2 errors",
"retryable": false,
"details": {
"errors": [
{ "instanceLocation": "/filters/year_min", "keyword": "type", "error": "must be an integer" },
{ "instanceLocation": "/filters/make", "keyword": "additionalProperties", "error": "unknown filter key" }
]
},
"created_at": "2026-04-30T10:15:30Z"
}
}
}

A lead.submit request with customer but no consent:

{
"type": "aap.error",
"error_id": "err_01HZ9CONSENT01",
"code": "CONTACT_CONSENT_REQUIRED",
"message": "Customer info present but no ConsentGrant. Provide a 'consent' block with scope ['lead_submission'].",
"retryable": false,
"details": {
"missing": "consent",
"expected_scope": "lead_submission"
},
"created_at": "2026-04-30T10:15:45Z"
}

Rate-limit example

{
"type": "aap.error",
"error_id": "err_01HZ9RATE01",
"code": "RATE_LIMITED",
"message": "Per-key rate limit exceeded.",
"retryable": true,
"details": {
"retry_after_ms": 30000
},
"created_at": "2026-04-30T10:16:00Z"
}

What dealer agents MUST and MUST NOT do

  • Dealer agents MUST return errors using this schema (typed aap.error payload), not free-text messages.
  • Dealer agents MUST NOT leak internal stack traces in message. Use details for structured diagnostic information that is safe to display.
  • Dealer agents MUST set retryable truthfully. Buyer agents follow this signal to decide whether to retry.