BerriAI/litellm · error · Exception
Missing keys={missing_keys} in environment.
Error message
Missing keys={missing_keys} in environment. What it means
Raised by BraintrustLogger.validate_environment when neither an explicit api_key argument nor the BRAINTRUST_API_KEY environment variable is present. LiteLLM custom logging integrations are constructed at proxy startup, so this usually surfaces as a crash or logged error during initialization of the braintrust callback rather than per-request.
Source
Thrown at litellm/integrations/braintrust_logging.py:67
"Content-Type": "application/json",
}
self._project_id_cache: dict[str, str] = {} # Cache mapping project names to IDs
self.global_braintrust_http_handler = get_async_httpx_client(llm_provider=httpxSpecialProvider.LoggingCallback)
self.global_braintrust_sync_http_handler = HTTPHandler()
def validate_environment(self, api_key: str | None):
"""
Expects
BRAINTRUST_API_KEY
in the environment
"""
missing_keys: Final = []
if api_key is None and os.getenv("BRAINTRUST_API_KEY", None) is None:
missing_keys.append("BRAINTRUST_API_KEY")
if len(missing_keys) > 0:
raise Exception(f"Missing keys={missing_keys} in environment.")
def get_project_id_sync(self, project_name: str) -> str:
"""
Get project ID from name, using cache if available.
If project doesn't exist, creates it.
"""
if project_name in self._project_id_cache:
return self._project_id_cache[project_name]
try:
response: Final = self.global_braintrust_sync_http_handler.post(
f"{self.api_base}/project",
headers=self.headers,
json={"name": project_name},
)
project_dict: Final = response.json()
project_id: Final = project_dict["id"]
self._project_id_cache[project_name] = project_idView on GitHub (pinned to 6c2dcb801b)
Solutions
- Export BRAINTRUST_API_KEY in the environment where the LiteLLM proxy starts: export BRAINTRUST_API_KEY=...
- In Docker/K8s, inject it via env or envFrom secret reference so the proxy process sees it
- Verify with printenv | grep BRAINTRUST inside the exact container that runs the proxy
- If braintrust logging is not intended, remove it from litellm_settings.callbacks / success_callback config
Example fix
# before litellm_settings: callbacks: [braintrust] # container starts without BRAINTRUST_API_KEY # after docker run --env BRAINTRUST_API_KEY=$BRAINTRUST_API_KEY ... ghcr.io/berriai/litellm:latest --config /app/config.yaml
Defensive patterns
Strategy: validation
Validate before calling
import os
def braintrust_ready() -> bool:
return bool(os.getenv("BRAINTRUST_API_KEY"))
if "braintrust" in callbacks and not braintrust_ready():
raise RuntimeError("braintrust callback enabled but BRAINTRUST_API_KEY missing") Try / catch
try:
logger = BraintrustLogger(...)
except Exception as e:
if "Missing keys" in str(e):
raise RuntimeError("Set BRAINTRUST_API_KEY before enabling the braintrust callback") from e
raise Prevention
- Fail fast at startup when callbacks are enabled without their env vars
- Wire secrets via container env/envFrom, not baked images
- Document required env vars per callback in the deployment checklist
When it happens
Trigger: Enabling the braintrust callback in litellm_settings.callbacks without exporting BRAINTRUST_API_KEY; running in a container/CI where the env var is not injected; passing api_key=None explicitly and relying solely on the environment.
Common situations: Docker/Kubernetes secrets not wired into the proxy container; .env file not loaded in the deployment; env var name typo (e.g. BRAINTRUST_KEY); disabling braintrust locally but the callback config leaked into shared config.
Related errors
- AZURE_SENTINEL_DCR_IMMUTABLE_ID is required. Set it as an en
- AZURE_SENTINEL_ENDPOINT is required. Set it as an environmen
- AZURE_SENTINEL_TENANT_ID or AZURE_TENANT_ID is required. Set
- AZURE_SENTINEL_CLIENT_ID or AZURE_CLIENT_ID is required. Set
- AZURE_SENTINEL_CLIENT_SECRET or AZURE_CLIENT_SECRET is requi
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/4fe974558ca41cf2.
Report an issue: GitHub.