Comprehensive error types for different failure modes.
All SDK errors extend from the base AgentsError class.
/**
* Base error class for all agent-related errors
*/
class AgentsError extends Error {
/** Error type identifier */
readonly type: string;
/** Error message */
message: string;
/** Stack trace */
stack?: string;
}Usage Examples:
import { AgentsError } from '@openai/agents';
try {
// Agent operation
} catch (error) {
if (error instanceof AgentsError) {
console.error('Agent error type:', error.type);
console.error('Error message:', error.message);
console.error('Stack trace:', error.stack);
}
}Errors caused by incorrect configuration or usage.
/**
* Error caused by user misconfiguration
* Indicates the user needs to fix their code or configuration
*/
class UserError extends AgentsError {
readonly type: 'user_error';
}Usage Examples:
import { Agent, run, UserError } from '@openai/agents';
try {
// Invalid agent configuration
const agent = new Agent({
name: 'Agent',
// Missing required fields or invalid configuration
});
await run(agent, 'Hello');
} catch (error) {
if (error instanceof UserError) {
console.error('Configuration error:', error.message);
console.error('Please check your agent configuration');
// Fix configuration and retry
}
}
// Common causes:
// - Missing required configuration fields
// - Invalid parameter types
// - Invalid tool definitions
// - Invalid output schemas
// - Incompatible optionsErrors from external systems (API, network, etc).
/**
* Error from external system (API, network, database, etc)
* Usually transient and may succeed on retry
*/
class SystemError extends AgentsError {
readonly type: 'system_error';
/** Original error from the system */
cause?: Error;
}Usage Examples:
import { Agent, run, SystemError } from '@openai/agents';
const agent = new Agent({
name: 'Agent',
instructions: 'You are helpful',
});
async function runWithRetry(maxRetries: number = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await run(agent, 'Hello');
} catch (error) {
if (error instanceof SystemError) {
console.error(`Attempt ${attempt} failed:`, error.message);
if (attempt < maxRetries) {
console.log('Retrying...');
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
} else {
console.error('Max retries reached');
throw error;
}
} else {
// Non-system error, don't retry
throw error;
}
}
}
}
await runWithRetry();
// Common causes:
// - API rate limits
// - Network timeouts
// - Service unavailable
// - Authentication failures
// - Database connection errorsErrors from unexpected model behavior.
/**
* Error caused by unexpected model behavior
* Model did something the SDK didn't expect or couldn't handle
*/
class ModelBehaviorError extends AgentsError {
readonly type: 'model_behavior_error';
/** Raw model response that caused the error */
rawResponse?: any;
}Usage Examples:
import { Agent, run, ModelBehaviorError } from '@openai/agents';
import { z } from 'zod';
const agent = new Agent({
name: 'DataAgent',
instructions: 'Extract data from text',
outputType: z.object({
name: z.string(),
age: z.number(),
}),
});
try {
const result = await run(agent, 'Extract data from: John Smith, age 30');
} catch (error) {
if (error instanceof ModelBehaviorError) {
console.error('Model behavior error:', error.message);
console.error('Raw response:', error.rawResponse);
// Possible solutions:
// - Adjust instructions to be clearer
// - Provide examples in prompt
// - Use different model
// - Simplify output schema
}
}
// Common causes:
// - Model returned invalid JSON for structured output
// - Model refused to use required tool
// - Model output doesn't match schema
// - Model called non-existent tool
// - Unexpected response formatError when agent exceeds maximum turn limit.
/**
* Error when agent exceeds maximum number of turns
* Agent got stuck in a loop or task requires more turns
*/
class MaxTurnsExceededError extends AgentsError {
readonly type: 'max_turns_exceeded_error';
/** Number of turns executed */
turnsExecuted: number;
/** Maximum turns allowed */
maxTurns: number;
}Usage Examples:
import { Agent, run, MaxTurnsExceededError } from '@openai/agents';
const agent = new Agent({
name: 'Agent',
instructions: 'You are helpful',
tools: [
/* tools */
],
});
try {
const result = await run(agent, 'Complex task', {
maxTurns: 10,
});
} catch (error) {
if (error instanceof MaxTurnsExceededError) {
console.error('Max turns exceeded');
console.error(`Executed: ${error.turnsExecuted}`);
console.error(`Maximum: ${error.maxTurns}`);
// Possible solutions:
// - Increase maxTurns limit
// - Simplify the task
// - Check for infinite loops in tools
// - Improve agent instructions
// - Break task into smaller steps
}
}
// Prevent infinite loops
const result = await run(agent, 'Task', {
maxTurns: 20, // Reasonable limit
});Error during tool execution.
/**
* Error during tool execution
* Tool threw an error or returned invalid result
*/
class ToolCallError extends AgentsError {
readonly type: 'tool_call_error';
/** Name of the tool that failed */
toolName: string;
/** Tool call ID */
callId: string;
/** Original error from tool */
cause: Error;
/** Input that was passed to the tool */
input?: any;
}Usage Examples:
import { Agent, run, tool, ToolCallError } from '@openai/agents';
import { z } from 'zod';
const riskyTool = tool({
name: 'risky_operation',
description: 'Performs a risky operation',
parameters: z.object({
value: z.number(),
}),
execute: async (input) => {
if (input.value < 0) {
throw new Error('Value must be positive');
}
return `Result: ${input.value}`;
},
errorFunction: (context, error) => {
// Custom error message to model
return `Operation failed: ${error.message}. Please try again with a positive value.`;
},
});
const agent = new Agent({
name: 'ToolAgent',
instructions: 'You use tools',
tools: [riskyTool],
});
try {
const result = await run(agent, 'Use the risky operation with -5');
} catch (error) {
if (error instanceof ToolCallError) {
console.error('Tool error:', error.message);
console.error('Tool name:', error.toolName);
console.error('Call ID:', error.callId);
console.error('Input:', error.input);
console.error('Cause:', error.cause);
// Handle tool-specific errors
if (error.toolName === 'risky_operation') {
console.log('The risky operation failed, trying alternative approach');
}
}
}
// Tool errors are usually handled gracefully by the agent
// The agent sees the error message and can try again
// Only catastrophic tool errors bubble up as ToolCallErrorError during guardrail execution.
/**
* Error during guardrail execution
* Guardrail code threw an error (not tripwire triggered)
*/
class GuardrailExecutionError extends AgentsError {
readonly type: 'guardrail_execution_error';
/** Name of the guardrail that failed */
guardrailName: string;
/** Original error from guardrail */
cause: Error;
}Usage Examples:
import { Agent, run, InputGuardrail, GuardrailExecutionError } from '@openai/agents';
const faultyGuardrail: InputGuardrail = {
name: 'faulty_check',
execute: async ({ input }) => {
// Guardrail code has a bug
throw new Error('Guardrail crashed');
},
};
const agent = new Agent({
name: 'GuardedAgent',
instructions: 'You are helpful',
inputGuardrails: [faultyGuardrail],
});
try {
await run(agent, 'Hello');
} catch (error) {
if (error instanceof GuardrailExecutionError) {
console.error('Guardrail execution failed');
console.error('Guardrail name:', error.guardrailName);
console.error('Error:', error.cause.message);
// Fix the guardrail code
// Or temporarily disable the guardrail
}
}Error when input guardrail blocks execution.
/**
* Error when input guardrail tripwire is triggered
* Input was blocked by guardrail policy
*/
class InputGuardrailTripwireTriggered extends AgentsError {
readonly type: 'input_guardrail_tripwire_triggered';
/** Guardrail results that were triggered */
guardrailResults: InputGuardrailResult[];
}
interface InputGuardrailResult {
/** Guardrail name */
name: string;
/** Whether tripwire was triggered */
tripwireTriggered: boolean;
/** Output information from the check */
outputInfo: any;
/** Error if guardrail execution failed */
error?: Error;
}Usage Examples:
import { Agent, run, InputGuardrail, InputGuardrailTripwireTriggered } from '@openai/agents';
const profanityGuardrail: InputGuardrail = {
name: 'profanity_check',
execute: async ({ input }) => {
const text = input.map(i => (i as any).content || '').join(' ');
const hasProfanity = /\b(badword)\b/i.test(text);
return {
tripwireTriggered: hasProfanity,
outputInfo: {
reason: hasProfanity ? 'Profanity detected' : 'Clean',
},
};
},
};
const agent = new Agent({
name: 'SafeAgent',
instructions: 'You are helpful',
inputGuardrails: [profanityGuardrail],
});
try {
await run(agent, 'Hello with badword in it');
} catch (error) {
if (error instanceof InputGuardrailTripwireTriggered) {
console.error('Input blocked by guardrail');
for (const result of error.guardrailResults) {
if (result.tripwireTriggered) {
console.error(`- ${result.name}: ${JSON.stringify(result.outputInfo)}`);
}
}
// Show user-friendly error
console.log('Your input was blocked. Please rephrase without inappropriate language.');
}
}Error when output guardrail blocks output.
/**
* Error when output guardrail tripwire is triggered
* Output was blocked by guardrail policy
*/
class OutputGuardrailTripwireTriggered extends AgentsError {
readonly type: 'output_guardrail_tripwire_triggered';
/** Guardrail results that were triggered */
guardrailResults: OutputGuardrailResult[];
/** Agent output that was blocked */
agentOutput: any;
}
interface OutputGuardrailResult {
/** Guardrail name */
name: string;
/** Whether tripwire was triggered */
tripwireTriggered: boolean;
/** Output information from the check */
outputInfo: any;
/** Error if guardrail execution failed */
error?: Error;
}Usage Examples:
import { Agent, run, OutputGuardrail, OutputGuardrailTripwireTriggered } from '@openai/agents';
const piiGuardrail: OutputGuardrail = {
name: 'pii_detection',
execute: async ({ agentOutput }) => {
const text = String(agentOutput);
const hasPII =
/\b\d{3}-\d{2}-\d{4}\b/.test(text) || // SSN
/\b\d{16}\b/.test(text); // Credit card
return {
tripwireTriggered: hasPII,
outputInfo: {
reason: hasPII ? 'PII detected in output' : 'No PII',
},
};
},
};
const agent = new Agent({
name: 'SecureAgent',
instructions: 'You are helpful but never share sensitive data',
outputGuardrails: [piiGuardrail],
});
try {
await run(agent, 'Tell me about user data');
} catch (error) {
if (error instanceof OutputGuardrailTripwireTriggered) {
console.error('Output blocked by guardrail');
console.error('Blocked output:', error.agentOutput);
for (const result of error.guardrailResults) {
if (result.tripwireTriggered) {
console.error(`- ${result.name}: ${JSON.stringify(result.outputInfo)}`);
}
}
// Return safe default response
console.log('I cannot share that information for security reasons.');
}
}Best practices for error handling.
Usage Examples:
import {
Agent,
run,
AgentsError,
UserError,
SystemError,
ModelBehaviorError,
MaxTurnsExceededError,
ToolCallError,
GuardrailExecutionError,
InputGuardrailTripwireTriggered,
OutputGuardrailTripwireTriggered,
} from '@openai/agents';
const agent = new Agent({
name: 'RobustAgent',
instructions: 'You are helpful',
tools: [
/* tools */
],
inputGuardrails: [
/* guardrails */
],
outputGuardrails: [
/* guardrails */
],
});
// Comprehensive error handling
async function safeRun(input: string, maxRetries: number = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await run(agent, input, {
maxTurns: 20,
});
} catch (error) {
// User errors - fix configuration
if (error instanceof UserError) {
console.error('Configuration error:', error.message);
throw error; // Don't retry, fix config
}
// System errors - retry with backoff
else if (error instanceof SystemError) {
console.error(`System error (attempt ${attempt}/${maxRetries}):`, error.message);
if (attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
console.log(`Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
// Model behavior errors - adjust and retry
else if (error instanceof ModelBehaviorError) {
console.error('Model behavior error:', error.message);
if (attempt < maxRetries) {
console.log('Simplifying request and retrying...');
// Could adjust instructions or prompt here
continue;
}
throw error;
}
// Max turns - increase limit or simplify
else if (error instanceof MaxTurnsExceededError) {
console.error('Max turns exceeded:', error.turnsExecuted);
throw error; // Don't retry, task too complex
}
// Tool errors - usually already handled by agent
else if (error instanceof ToolCallError) {
console.error('Tool call failed:', error.toolName);
throw error;
}
// Guardrail errors - fix guardrail code
else if (error instanceof GuardrailExecutionError) {
console.error('Guardrail execution error:', error.guardrailName);
throw error; // Don't retry, fix guardrail
}
// Input blocked - show user-friendly message
else if (error instanceof InputGuardrailTripwireTriggered) {
console.error('Input blocked by guardrails');
for (const result of error.guardrailResults) {
if (result.tripwireTriggered) {
console.error(`- ${result.name}`);
}
}
throw new Error('Your input violates our content policy. Please rephrase.');
}
// Output blocked - return safe message
else if (error instanceof OutputGuardrailTripwireTriggered) {
console.error('Output blocked by guardrails');
return {
finalOutput: 'I cannot provide that information.',
} as any;
}
// Unknown error
else {
console.error('Unknown error:', error);
throw error;
}
}
}
throw new Error('Max retries exceeded');
}
// Usage
try {
const result = await safeRun('Hello!');
console.log('Success:', result.finalOutput);
} catch (error) {
if (error instanceof AgentsError) {
// Log to error tracking service
console.error('AgentsError:', error.type, error.message);
} else {
console.error('Unexpected error:', error);
}
}Integrate errors with logging and monitoring systems.
Usage Examples:
import { Agent, run, AgentsError } from '@openai/agents';
// Error logger
class ErrorLogger {
static log(error: any, context: any) {
const errorData = {
timestamp: new Date().toISOString(),
type: error instanceof AgentsError ? error.type : 'unknown',
message: error.message,
stack: error.stack,
context,
};
// Log to console
console.error('Error:', JSON.stringify(errorData, null, 2));
// Send to error tracking service
// Sentry, Datadog, etc.
// sentry.captureException(error, { extra: errorData });
}
}
const agent = new Agent({
name: 'MonitoredAgent',
instructions: 'You are helpful',
});
try {
const result = await run(agent, 'Hello', {
context: { userId: 'user-123', requestId: 'req-456' },
});
} catch (error) {
ErrorLogger.log(error, {
agent: agent.name,
input: 'Hello',
userId: 'user-123',
});
// Decide how to handle based on error type
if (error instanceof AgentsError) {
// Send appropriate response to user
switch (error.type) {
case 'input_guardrail_tripwire_triggered':
console.log('Please rephrase your message.');
break;
case 'system_error':
console.log('Service temporarily unavailable. Please try again.');
break;
default:
console.log('An error occurred. Please contact support.');
}
}
}Different recovery strategies for different error types.
Usage Examples:
import { Agent, run, AgentsError } from '@openai/agents';
const agent = new Agent({
name: 'ResilientAgent',
instructions: 'You are helpful',
});
// Strategy 1: Retry with exponential backoff
async function retryWithBackoff(input: string, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await run(agent, input);
} catch (error) {
if (error instanceof SystemError && i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
continue;
}
throw error;
}
}
}
// Strategy 2: Fallback to simpler approach
async function runWithFallback(input: string) {
try {
return await run(agent, input, {
modelSettings: { temperature: 0.7 },
});
} catch (error) {
if (error instanceof ModelBehaviorError) {
console.log('Falling back to simpler approach...');
return await run(agent, `Please answer simply: ${input}`, {
modelSettings: { temperature: 0.3 },
});
}
throw error;
}
}
// Strategy 3: Circuit breaker
class CircuitBreaker {
private failures = 0;
private lastFailure = 0;
private threshold = 5;
private timeout = 60000; // 1 minute
async execute(fn: () => Promise<any>) {
// Check if circuit is open
if (
this.failures >= this.threshold &&
Date.now() - this.lastFailure < this.timeout
) {
throw new Error('Circuit breaker is open');
}
try {
const result = await fn();
this.failures = 0; // Reset on success
return result;
} catch (error) {
this.failures++;
this.lastFailure = Date.now();
throw error;
}
}
}
const breaker = new CircuitBreaker();
async function runWithCircuitBreaker(input: string) {
return await breaker.execute(() => run(agent, input));
}