BerriAI/litellm · error · ValueError

NIMBLE_API_KEY is not set. Set `NIMBLE_API_KEY` environment

Error message

NIMBLE_API_KEY is not set. Set `NIMBLE_API_KEY` environment variable.

What it means

Raised by litellm's Nimble web-search transformer when resolve_server_api_key cannot find a key: no api_key argument and no NIMBLE_API_KEY environment variable. It is raised while building request headers, before any HTTP call to Nimble's search API.

Source

Thrown at litellm/llms/nimble/search/transformation.py:110

        api_key: str | None = None,
        api_base: str | None = None,
        **kwargs: object,  # kwargs-ok: BaseSearchConfig.validate_environment signature
    ) -> dict[str, str]:  # mutable-ok: the http handler passes this straight to httpx as headers
        """
        Validate environment and return headers.

        Returns a new dict rather than mutating ``headers``: the http handler calls this
        a second time after ``litellm/search/main.py`` already did, so it has to be idempotent.
        """
        resolved_api_key: Final = self.resolve_server_api_key(
            caller_api_key=api_key,
            caller_api_base=api_base,
            key_env_vars=("NIMBLE_API_KEY",),
            base_env_var="NIMBLE_API_BASE",
            default_api_base=self.NIMBLE_API_BASE,
        )
        if not resolved_api_key:
            raise ValueError("NIMBLE_API_KEY is not set. Set `NIMBLE_API_KEY` environment variable.")
        return {  # mutable-ok: httpx requires a plain dict of headers
            **headers,
            "Authorization": f"Bearer {resolved_api_key}",
            "Content-Type": "application/json",
            # Nimble's client-attribution header: names the calling software, nothing else.
            "X-Client-Source": "litellm",
        }

    def get_complete_url(
        self,
        api_base: str | None,
        optional_params: dict[str, object],  # mutable-ok: BaseSearchConfig.get_complete_url signature
        data: dict[str, object] | list[dict[str, object]] | None = None,  # mutable-ok: base signature
        **kwargs: object,  # kwargs-ok: BaseSearchConfig.get_complete_url signature
    ) -> str:
        resolved_base: Final = (api_base or get_secret_str("NIMBLE_API_BASE") or self.NIMBLE_API_BASE).rstrip("/")
        if resolved_base.endswith("/search"):
            return resolved_base

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. export NIMBLE_API_KEY=<key from nimble.com> in the environment running litellm.
  2. Or pass api_key explicitly on the search call / in the proxy config for the nimble engine.
  3. Restart the process after exporting so the env var is visible.
  4. If overriding the endpoint, also set NIMBLE_API_BASE correctly.

Example fix

# before
results = litellm.search(query="latest ai news", engine="nimble")

# after
results = litellm.search(
    query="latest ai news",
    engine="nimble",
    api_key=os.environ["NIMBLE_API_KEY"],
)
Defensive patterns

Strategy: validation

Validate before calling

import os
if not os.getenv("NIMBLE_API_KEY"):
    raise RuntimeError("NIMBLE_API_KEY not set; required for engine='nimble'")

Try / catch

try:
    results = litellm.search(query=q, engine="nimble")
except ValueError as e:
    if "NIMBLE_API_KEY is not set" in str(e):
        raise RuntimeError("Config error: NIMBLE_API_KEY missing") from e
    raise

Prevention

When it happens

Trigger: Calling litellm.search() (or the /v1/search endpoint on the proxy) with engine='nimble' without an api_key param and without NIMBLE_API_KEY set in the environment.

Common situations: Forgetting the env var when switching a search job to Nimble, proxy deployment missing the secret, or assuming the generic search API key covers all engines.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/144401ff7595ca83. Report an issue: GitHub.