crewAIInc/crewAI · error · ValueError

BRAVE_API_KEY environment variable is required

Error message

BRAVE_API_KEY environment variable is required

What it means

BraveSearchTool resolves its credential at construction: the api_key constructor argument, or else the BRAVE_API_KEY environment variable. If both are empty it raises ValueError immediately — the key is sent as the x-subscription-token header on every request and the API refuses anonymous calls.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/brave_search_tool/base.py:128

        ]
    )

    def __init__(
        self,
        *,
        api_key: str | None = None,
        headers: dict[str, Any] | None = None,
        requests_per_second: float = 1.0,
        save_file: bool = False,
        raw: bool = False,
        timeout: int = 30,
        **kwargs: Any,
    ):
        super().__init__(**kwargs)

        self._api_key = api_key or os.environ.get("BRAVE_API_KEY")
        if not self._api_key:
            raise ValueError("BRAVE_API_KEY environment variable is required")

        self.raw = bool(raw)
        self._timeout = int(timeout)
        self.save_file = bool(save_file)
        self._requests_per_second = float(requests_per_second)
        self._headers = self._build_and_validate_headers(headers or {})
        # Per-instance rate limiting: each instance has its own clock and lock.
        # Total process rate is the sum of limits of instances you create.
        self._last_request_time: float = 0
        self._rate_limit_lock = threading.Lock()

    @property
    def api_key(self) -> str | None:
        return self._api_key

    @property
    def headers(self) -> dict[str, Any]:
        return self._headers

View on GitHub (pinned to 754d7323be)

Solutions

  1. Export the key: `export BRAVE_API_KEY=BSA...` from the Brave Search API dashboard.
  2. Or pass it explicitly: BraveSearchTool(api_key='BSA...').
  3. Verify in the running process: `python -c "import os; print(bool(os.getenv('BRAVE_API_KEY')))"`.
  4. Wire the secret in CI/Docker environment configuration.

Example fix

# before
tool = BraveSearchTool()

# after
tool = BraveSearchTool(api_key=os.environ["BRAVE_API_KEY"])  # fails fast with KeyError if unset
Defensive patterns

Strategy: validation

Validate before calling

import os

if not (os.getenv("BRAVE_API_KEY")):
    raise SystemExit("BRAVE_API_KEY is required; get it from https://api-dashboard.search.brave.com")

Try / catch

try:
    tool = BraveSearchTool()
except ValueError as e:
    if "BRAVE_API_KEY" in str(e):
        os.environ["BRAVE_API_KEY"] = secret_store.get("brave")
        tool = BraveSearchTool()
    else:
        raise

Prevention

When it happens

Trigger: Instantiating BraveSearchTool() with no api_key while BRAVE_API_KEY is unset; env var set in a different shell/session/notebook kernel; secret file loaded after construction.

Common situations: Forgot to export the key; using BRAVE_SEARCH_API_KEY (wrong name); CI secrets not injected; .env not loaded before tool creation.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/1ca57693ea5bad17. Report an issue: GitHub.