Skip to Content
GuidesError Handling

Error Handling

This guide covers how to handle errors from the Relynt gateway, including HTTP error codes, retry strategies, and timeout handling.

HTTP error codes

StatusCodeDescriptionAction
400bad_requestInvalid request body (missing or malformed fields)Fix the request and retry
401unauthorizedInvalid or missing agent credentialCheck credential, rotate if needed
403forbiddenAgent not authorized for this organizationVerify agent registration
409conflictIdempotency key reused with different parametersUse a new idempotency key
422policy_errorPolicy evaluation failedCheck policy configuration
429rate_limitedToo many requestsBack off and retry
500internal_errorServer errorRetry with backoff
503unavailableService temporarily unavailableRetry with backoff

Retry strategies

Idempotent retries

Always include an Idempotency-Key header so retries are safe:

async function callGatewayWithRetry( params: RequestParams, maxRetries = 3 ): Promise<GatewayResponse> { const idempotencyKey = crypto.randomUUID(); for (let attempt = 0; attempt <= maxRetries; attempt++) { try { const response = await fetch( `${BASE_URL}/v1/agent-tool-call`, { method: "POST", headers: { Authorization: `Bearer ${AGENT_ID}:${AGENT_SECRET}`, "Idempotency-Key": idempotencyKey, "Content-Type": "application/json", }, body: JSON.stringify(params), } ); if (response.status === 429 || response.status >= 500) { const delay = Math.pow(2, attempt) * 1000; await new Promise((r) => setTimeout(r, delay)); continue; } return await response.json(); } catch (err) { if (attempt === maxRetries) throw err; const delay = Math.pow(2, attempt) * 1000; await new Promise((r) => setTimeout(r, delay)); } } throw new Error("Max retries exceeded"); }

Exponential backoff

Use exponential backoff for 429 and 5xx errors:

AttemptDelay
11 second
22 seconds
34 seconds
48 seconds

The Idempotency-Key ensures that retries don’t create duplicate actions. If a previous request succeeded but the response was lost, the retry returns the original result.

Handling pending approvals

When you receive pending_approval, the agent needs to wait for a human decision:

if (result.decision === "pending_approval") { // Option 1: Poll for the decision const approval = await client.pollApproval({ approvalId: result.approvalId!, timeoutMs: 300_000, // 5 minutes }); // Option 2: Proceed with a fallback console.log("Approval pending, queuing for later"); // Option 3: Inform the user console.log(`Action requires approval: ${result.approvalId}`); }

Timeout handling

Set appropriate timeouts for your agent’s use case:

ScenarioRecommended timeout
Standard gateway call30 seconds
Approval polling5–15 minutes
Connector with slow target API60 seconds

If a gateway call times out, always check the receipt before retrying. The action may have been executed even if you didn’t receive the response.

Last updated on