Error Handling
Handle current Veto SDK errors.
Tool Denials
Wrapped tools throw ToolCallDeniedError before execution when Guard returns deny or require_approval.
import { ToolCallDeniedError } from "veto-sdk";
try {
await safeTool.execute({ amount_usd: 900 });
} catch (error) {
if (error instanceof ToolCallDeniedError) {
console.error(error.toolName, error.decision, error.reason);
return;
}
throw error;
}Guard API Errors
Direct Guard calls can throw GuardApiError for transport or API failures.
import { GuardApiError } from "veto-sdk";
try {
await veto.guard("issue_refund", { amount_usd: 900 });
} catch (error) {
if (error instanceof GuardApiError) {
console.error(error.status, error.code, error.message);
}
}Approval Timeouts
When you opt into approvalMode: "wait", unresolved approvals can time out.
import { ApprovalTimeoutError } from "veto-sdk";
try {
await safeTool.execute({ amount_usd: 900 });
} catch (error) {
if (error instanceof ApprovalTimeoutError) {
console.error(error.approvalId);
}
}Best Practices
- Treat denials as product-visible outcomes, not crashes.
- Feed clear denial messages back to the model or user.
- Do not retry denied calls with the same arguments.
- Use direct
veto.guard()calls for non-blocking observation before switching to wrapped execution.

