BerriAI/litellm · critical · Exception

Error: {response.status_code} - {response.text}

Error message

Error: {response.status_code} - {response.text}

What it means

LiteLLM's OpenAI Evals transformation requires an API key to build the Authorization header for evals endpoints. The lookup order is: litellm_params.api_key -> litellm.api_key -> litellm.openai_key -> the OPENAI_API_KEY environment variable (via the secret manager). If every source is empty, this ValueError is raised before any HTTP request is made - it is a local configuration error, not an upstream API error.

Source

Thrown at cookbook/misc/migrate_proxy_config.py:81

        confirm = input(
            "\033[92mDo you want to send the POST request with the above parameters? (y/n): \033[0m"
        )
        if confirm.lower() != "y":
            print("Aborting POST request.")
            exit()

        # Step 3: Call <proxy-base-url>/model/new for each model
        url = f"{proxy_base_url}/model/new"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {master_key}",
        }
        data = {"model_name": model_name, "litellm_params": litellm_params}
        print("POSTING data to proxy url", url)
        response = requests.post(url, headers=headers, json=data)
        if response.status_code != 200:
            print(f"Error: {response.status_code} - {response.text}")
            raise Exception(f"Error: {response.status_code} - {response.text}")

        # Print the response for each model
        print(
            f"Response for model '{model_name}': Status Code:{response.status_code} - {response.text}"
        )


# Usage
config_file = "config.yaml"
proxy_base_url = "http://0.0.0.0:4000"
master_key = "sk-1234"
print(f"config_file: {config_file}")
print(f"proxy_base_url: {proxy_base_url}")
migrate_models(config_file, proxy_base_url)

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Export OPENAI_API_KEY in the shell or CI environment: export OPENAI_API_KEY=sk-...
  2. Or set it in code before the eval call: litellm.api_key = 'sk-...'.
  3. Or pass api_key explicitly in the litellm_params of the eval request.
  4. If using a secret manager, confirm the secret name is exactly OPENAI_API_KEY and reachable.

Example fix

# before
result = litellm.acreate_eval(...)  # no key anywhere

# after
import os
os.environ["OPENAI_API_KEY"] = "sk-..."  # or pass api_key in litellm_params
result = litellm.acreate_eval(..., api_key="sk-...")
Defensive patterns

Strategy: validation

Validate before calling

import os, litellm

def evals_api_key_present() -> bool:
    return bool(
        litellm.api_key or litellm.openai_key or os.environ.get("OPENAI_API_KEY")
    )

assert evals_api_key_present(), "set OPENAI_API_KEY before running evals"

Try / catch

try:
    result = litellm.acreate_eval(...)
except ValueError as e:
    if "OPENAI_API_KEY is required" in str(e):
        os.environ["OPENAI_API_KEY"] = load_key_from_vault()
        result = litellm.acreate_eval(...)
    else:
        raise

Prevention

When it happens

Trigger: Calling litellm eval APIs (create/retrieve eval runs against OpenAI) without passing api_key in the request, without setting litellm.api_key / litellm.openai_key in code, and without OPENAI_API_KEY in the environment (or in a configured secret manager).

Common situations: New eval workflows where the developer relied only on a router-level key not visible to the evals path; CI environments lacking env vars; .env files not loaded before the call; key stored under a different name (e.g. OPENAI_API_KEY_BYPASS) without aliasing.

Related errors


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