Exceptions & Error Handling

Robust applications must handle network failures, authentication errors, and API rate limits gracefully. The Tavily SDK maps HTTP error codes returned by the API into strictly typed Python Exceptions, found in the tavily.errors module.

Available Exceptions

MissingAPIKeyError

  • Triggered When: The SDK is initialized without an explicit api_key argument, AND the TAVILY_API_KEY environment variable is not found on the system.
  • How to Handle: This is a fatal configuration error. Ensure your .env files are loaded before calling TavilyClient(), or check your server deployment environment variables.

InvalidAPIKeyError

  • Triggered When: The API returns an HTTP 401 Unauthorized status. This occurs if your key is malformed, expired, revoked, or belongs to a deleted account.
  • How to Handle: Catch this error and alert your system administrator. Your application will not function until a new, valid key is provided.

UsageLimitExceededError

  • Triggered When: The API returns an HTTP 429 Too Many Requests status.
  • Why it happens: This triggers in two scenarios:
    1. Rate Limiting: You are making too many requests per second based on your current tier.
    2. Depleted Credits: Your account has reached 0 API credits for the current billing cycle.
  • How to Handle: Implement an exponential backoff retry strategy, or check your Tavily dashboard to ensure your credit balance is sufficient.

ForbiddenError

  • Triggered When: The API returns HTTP 403, 432, or 433 errors.
  • Why it happens: Typically occurs when a specific API endpoint or feature (like deep Crawling) is not authorized for your current subscription tier, or if a security block triggered.

BadRequestError

  • Triggered When: The API returns HTTP 400 Bad Request.
  • Why it happens: A parameter you passed is invalid, malformed, or mutually exclusive. The exception message will usually contain the API's detailed error string explaining exactly which parameter failed validation.

TimeoutError

  • Triggered When: The HTTP request takes longer than the specified timeout parameter (defaults vary by method, typically 30-150 seconds).
  • How to Handle: If querying notoriously slow websites with Extract or Crawl, you may need to catch this error and retry, or simply pass a higher timeout=X float parameter into the method.

Example: Resilient Error Handling

Below is an example of wrapping a Tavily search within a robust, production-ready try/except block.

import time
from tavily import TavilyClient
from tavily.errors import (
    InvalidAPIKeyError, 
    UsageLimitExceededError, 
    BadRequestError, 
    TimeoutError
)

client = TavilyClient()

def safe_search(query: str, max_retries: int = 3):
    retries = 0

    while retries < max_retries:
        try:
            # Attempt the search
            response = client.search(query, timeout=10.0)
            return response

        except UsageLimitExceededError as e:
            print(f"Rate limit hit: {e}. Retrying in {2 ** retries} seconds...")
            time.sleep(2 ** retries) # Exponential backoff
            retries += 1

        except TimeoutError:
            print("Request timed out. Retrying...")
            retries += 1

        except BadRequestError as e:
            # A bad request won't be fixed by a retry. Fail immediately.
            print(f"Fatal parameter error: {e}")
            break

        except InvalidAPIKeyError as e:
            # Authentication failed. Fail immediately.
            print(f"Authentication Error: {e}")
            break

        except Exception as e:
            # Catch any other generic exceptions (like connection drops)
            print(f"Unexpected system error: {e}")
            break

    return None