Skip to content
/docs

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

  1. Treat denials as product-visible outcomes, not crashes.
  2. Feed clear denial messages back to the model or user.
  3. Do not retry denied calls with the same arguments.
  4. Use direct veto.guard() calls for non-blocking observation before switching to wrapped execution.