or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

agents.mderrors.mdguardrails.mdhandoffs.mdindex.mdmcp.mdmodels.mdrealtime.mdsessions.mdtools.mdtracing.md
tile.json

errors.mddocs/

Error Handling

Comprehensive error types for different failure modes.

Capabilities

Base Error Class

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);
  }
}

User Error

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 options

System Error

Errors 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 errors

Model Behavior Error

Errors 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 format

Max Turns Exceeded Error

Error 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
});

Tool Call Error

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 ToolCallError

Guardrail Execution Error

Error 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
  }
}

Input Guardrail Tripwire Triggered

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.');
  }
}

Output Guardrail Tripwire Triggered

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.');
  }
}

Error Handling Patterns

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);
  }
}

Error Logging and Monitoring

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.');
    }
  }
}

Error Recovery Strategies

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));
}