Error Reference
AgentBridge returns consistent, machine-readable error responses for every failure mode. This page documents every possible error code, what causes it, how to resolve it, and whether it is safe to retry. It also includes provider-specific error examples and a complete retry function implementation.
Error Response Shape #
All error responses share the same JSON envelope. The providerError field is only present on 422 responses where the upstream provider returned an error.
interface AgentBridgeErrorResponse {
statusCode: number; // HTTP status code (400, 401, 403, 404, 409, 422, 429, 500, 502)
message: string; // Human-readable error description
error: string; // HTTP status text (e.g. "Not Found", "Unauthorized")
providerError?: object; // Present on 422 only — raw error from upstream provider
}
Error Codes #
| Status | Error | Common Cause | How to Fix | Retryable |
|---|---|---|---|---|
| 400 | Bad Request | Missing required fields (provider, tool, params), wrong data types, or provider integration not connected |
Check the request body against the Execute Tool docs. Connect the provider integration if missing. | No |
| 401 | Unauthorized | API key missing from headers, malformed (does not match ab_live_ + 40 chars), or revoked |
Check the Authorization: Bearer header. Generate a new key if the current one was revoked. |
No |
| 403 | Forbidden | API key is valid but its scope does not permit the requested operation (e.g. read key calling execute) |
Create a new key with the required scope (write for execute, admin for key management). |
No |
| 404 | Not Found | Resource does not exist: tool name typo, log ID not found, or API key ID not found | Verify the tool name against the Integrations docs. Check the resource ID. | No |
| 409 | Conflict | Integration for this provider already exists for this user | Disconnect the existing integration before reconnecting, or use the existing one. | No |
| 422 | Unprocessable Entity | AgentBridge called the upstream provider successfully, but the provider rejected the request | Inspect providerError for the raw upstream error. Fix the tool params or resolve provider-side permissions. |
No |
| 429 | Too Many Requests | Rate limit exceeded for this API key or account | Wait until the Unix timestamp in X-RateLimit-Reset, then retry once. |
Yes |
| 500 | Internal Server Error | Unexpected server-side error in AgentBridge | Retry with exponential backoff. Contact support if persistent. | Yes |
| 502 | Bad Gateway | Upstream provider API was unreachable, timed out, or returned an invalid response | Retry after a short delay (5-10s). Check the provider's status page if it persists. | Yes |
422 — Provider Errors in Detail #
The providerError field contains the raw error body from the upstream provider (Notion, Slack, GitHub, etc.). Its structure varies by provider — AgentBridge does not normalize provider error formats. Always check the provider-specific error code and message to understand what went wrong.
Notion — Permission Error #
Returned when the Notion integration does not have access to the requested page or database. Re-authorize the integration and ensure the page is shared with the AgentBridge integration in Notion.
{
"statusCode": 422,
"message": "Provider returned an error",
"error": "Unprocessable Entity",
"providerError": {
"object": "error",
"status": 403,
"code": "restricted_resource",
"message": "Insufficient permissions. Ensure the integration has access to this page."
}
}
Slack — Channel Not Found #
Returned when the channel ID does not exist or the Slack bot has not been invited to the channel. Use list_channels to get valid channel IDs, and invite the bot to private channels.
{
"statusCode": 422,
"message": "Provider returned an error",
"error": "Unprocessable Entity",
"providerError": {
"ok": false,
"error": "channel_not_found"
}
}
GitHub — Repository Not Found #
Returned when the repository does not exist or the PAT does not have access. Verify the repo parameter uses owner/repo format and the token has the repo scope.
{
"statusCode": 422,
"message": "Provider returned an error",
"error": "Unprocessable Entity",
"providerError": {
"message": "Not Found",
"documentation_url": "https://docs.github.com/rest/repos/repos#get-a-repository"
}
}
Retry Guidance #
| Status | Retryable | Strategy | Max Attempts |
|---|---|---|---|
| 429 | Yes | Wait until the Unix timestamp in X-RateLimit-Reset, then retry once. | 1 |
| 500 | Yes | Exponential backoff: 1s, 2s, 4s, 8s between attempts. | 3 |
| 502 | Yes | Fixed delay: wait 5-10 seconds, then retry. Check provider status if persistent. | 2 |
| 400 | No | Fix the request body or connect the integration. Retrying will not help. | 0 |
| 401 | No | Fix or regenerate the API key. Retrying with the same key will not help. | 0 |
| 403 | No | Use a key with the required scope. | 0 |
| 404 | No | Fix the tool name, resource ID, or connect the integration. | 0 |
| 422 | No | Fix the params or resolve the provider-side permission issue. | 0 |
TypeScript Error Handling #
Here is a production-ready retry function that handles all AgentBridge error types correctly. It retries only retryable errors and uses exponential backoff:
import { AgentBridge, AgentBridgeError } from 'agentbridge-sdk';
import type { ExecuteParams, ExecuteResult } from 'agentbridge-sdk';
const RETRYABLE_CODES = new Set([429, 500, 502]);
async function executeWithRetry(
bridge: AgentBridge,
params: ExecuteParams,
maxRetries = 3,
): Promise<ExecuteResult> {
let attempt = 0;
while (true) {
try {
return await bridge.execute(params);
} catch (err) {
if (!(err instanceof AgentBridgeError)) {
throw err; // Network error or unexpected exception
}
const isRetryable = RETRYABLE_CODES.has(err.statusCode);
attempt++;
if (!isRetryable || attempt >= maxRetries) {
// Log provider error details for debugging
if (err.statusCode === 422 && err.providerError) {
console.error(
'[AgentBridge] Provider error:',
JSON.stringify(err.providerError, null, 2),
);
}
throw err;
}
// Calculate delay: exponential backoff for 500/502, fixed for 429
const delay = err.statusCode === 429
? 5000 // Wait 5s for rate limits (or parse X-RateLimit-Reset)
: Math.pow(2, attempt) * 1000; // 2s, 4s, 8s
console.warn(
`[AgentBridge] Retrying in ${delay}ms (attempt ${attempt}/${maxRetries}, status ${err.statusCode})`,
);
await new Promise(r => setTimeout(r, delay));
}
}
}
// Usage:
const bridge = new AgentBridge(process.env.AGENTBRIDGE_API_KEY!);
const result = await executeWithRetry(bridge, {
provider: 'notion',
tool: 'create_page',
params: { parent_id: 'abc', title: 'Report' },
});