Error Handling
The TypeScript SDK throws ConfigureError for API, validation, permission, and network failures.
ts
import { ConfigureError, ErrorCode } from "configure";
try {
await profile.executeTool(toolCall);
} catch (error) {
if (error instanceof ConfigureError) {
if (error.code === ErrorCode.ACCESS_DENIED) {
// Tool was not enabled, user permission is missing, or the action is blocked.
}
if (error.code === ErrorCode.TOOL_NOT_CONNECTED) {
// Prompt the user to connect the required connector.
}
}
}Common cases:
- Invalid agent handle: constructor validation fails before a request is sent.
- Disabled tool:
profile.executeTool()rejects connector/action calls not enabled byprofile.tools(options). - Missing connector: connector-backed calls fail with
TOOL_NOT_CONNECTED. Other connector/provider failures surface asTOOL_ERROR. - Rate limit: reads may fail with
RATE_LIMITED(HTTP 429). - Quota exhausted: billing/quota limits surface as
PAYMENT_REQUIRED(HTTP 402), notRATE_LIMITED. - Failed forget:
profile.forget()with an unknown id, or an id outside the agent's own namespace, returns HTTP 400 with a flat error body and surfaces asINVALID_INPUT. Do not retry, and do not expectNOT_FOUND. - Permission filtering: search may return fewer results with
filteredmetadata instead of throwing.
ErrorCode covers more than the two above. The ones a hardening integration must handle:
| Code | When | What to do |
|---|---|---|
AUTH_REQUIRED | The user's token is missing or expired | Re-run sign-in / refresh the OAuth token |
API_KEY_MISSING | No apiKey/CONFIGURE_API_KEY | Fix server config |
ACCESS_DENIED | Tool not enabled, permission missing, action blocked | Route to connect/permission/approval UI |
TOOL_NOT_CONNECTED | Connector-backed call for an unconnected app | Prompt the user to connect it |
TOOL_ERROR | Connector/provider operation failed (not a connection problem) | Surface the message to the user; retry once if retryable is true |
RATE_LIMITED | Too many requests (HTTP 429) | Back off using retryAfter |
PAYMENT_REQUIRED | Quota exceeded (HTTP 402) | Backoff does not help; send the user to their plan via the response upgrade_url |
COMMIT_REQUIRED | A read obligation is open (read-then-read without commit) | Call profile.commit({...}) with the bounded runtime packet (messages, toolResults, and/or memories), then retry the read |
INVALID_INPUT | Bad arguments (e.g. invalid agent handle at construction, failed forget) | Fix the call; not retryable |
TIMEOUT / NETWORK_ERROR / SERVER_ERROR | Transient transport/server failure | Treat TIMEOUT and NETWORK_ERROR as retryable by code; retryable is undefined on client-side transport errors. Check retryable only on server-sourced errors such as SERVER_ERROR and RATE_LIMITED |
ConfigureError carries structured fields: code, statusCode, type, param, retryable, retryAfter, suggestedAction, docUrl, requestId. Branch on retryable/retryAfter for backoff rather than parsing messages. Do not parse error strings. Use ConfigureError.code and structured fields.