Skip to main content
Version: v0.11.2

Error Recovery

Every PEAC error definition includes a next_action hint -- a closed vocabulary of recovery actions that agents can take without human intervention. This enables automated error handling in agent-to-agent workflows.


Recovery vocabulary

ActionWhen to useAgent behavior
retry_after_delayTransient failure (rate limit, temporary unavailability)Wait and retry the same operation
retry_with_different_keyKey not found or key expiredTry a different kid or refresh JWKS
retry_with_different_inputInput validation failureModify the input and retry
refresh_attestationAttestation expired or staleObtain a fresh attestation and retry
contact_issuerIssuer-side configuration errorEscalate to issuer (not automatically recoverable)
abortUnrecoverable error (invalid signature, tampered receipt)Stop processing; do not retry
noneInformational error (no action needed)Log and continue

Using recovery hints

Every error returned by PEAC verification and issuance functions includes the next_action field:

error-handling.ts
import { verifyReceipt } from '@peac/protocol';

const result = await verifyReceipt(receipt, { issuerUrl });

if (!result.verified) {
for (const failure of result.failures) {
switch (failure.next_action) {
case 'retry_after_delay':
await sleep(failure.retry_after ?? 1000);
// Retry the same verification
break;

case 'retry_with_different_key':
// Refresh JWKS cache and retry
break;

case 'abort':
// Unrecoverable -- log and stop
console.error(`Verification failed: ${failure.message}`);
break;

default:
console.warn(`Unhandled action: ${failure.next_action}`);
}
}
}

Error structure

ErrorDefinition
interface ErrorDefinition {
code: string; // e.g., 'SIGNATURE_INVALID'
message: string; // Human-readable description
category: string; // Error category
retryable: boolean; // Whether retry may succeed
next_action: NextAction; // Agent-actionable recovery hint
retry_after?: number; // Suggested delay in milliseconds (optional)
}

The retryable boolean provides a quick check: if false, the error is deterministic and retrying with the same input will produce the same failure. The next_action provides more specific guidance on what to change before retrying.


Common error patterns

Expired receipt

code: RECEIPT_EXPIRED
retryable: false
next_action: refresh_attestation

The receipt's exp claim has passed. The agent should request a fresh receipt from the issuer.

Key not found

code: KEY_NOT_FOUND
retryable: true
next_action: retry_with_different_key

The kid in the receipt header does not match any key in the issuer's JWKS. The JWKS cache may be stale; refresh and retry.

Invalid signature

code: SIGNATURE_INVALID
retryable: false
next_action: abort

The Ed25519 signature does not verify against the public key. This is unrecoverable -- the receipt has been tampered with or was signed by a different key.

Rate limited

code: RATE_LIMITED
retryable: true
next_action: retry_after_delay
retry_after: 5000

The verification service is rate limiting requests. Wait the suggested delay and retry.


Transport-neutral

Recovery hints are transport-neutral. They work the same way regardless of whether the error occurs during HTTP verification, MCP tool calls, or A2A message processing. The next_action vocabulary is part of the protocol, not tied to any specific transport.


Next steps