BerriAI/litellm · error · Exception
Failed to register project: {e.response.text}
Error message
Failed to register project: {e.response.text} What it means
Exception raised by BraintrustLogger.get_project_id_sync when the POST to {api_base}/project returns an HTTP error status (httpx.HTTPStatusError). The message contains only the raw Braintrust API response body, so the actual status code must be inferred from the body text. This runs on the sync logging path the first time a given project_name is seen (results are cached in _project_id_cache afterwards).
Source
Thrown at litellm/integrations/braintrust_logging.py:88
"""
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_id
return project_id
except httpx.HTTPStatusError as e:
raise Exception(f"Failed to register project: {e.response.text}")
async def get_project_id_async(self, project_name: str) -> str:
"""
Async version of get_project_id_sync
"""
if project_name in self._project_id_cache:
return self._project_id_cache[project_name]
try:
response: Final = await self.global_braintrust_http_handler.post(
f"{self.api_base}/project/register",
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_id
return project_idView on GitHub (pinned to 77b7c6c40c)
Solutions
- Verify the key: curl -H "Authorization: Bearer $BRAINTRUST_API_KEY" https://api.braintrust.dev/v1/project
- Update BRAINTRUST_API_KEY if rotated and restart the proxy (cache is per-process)
- Simplify the project name to plain alphanumerics/dashes and retry
- Inspect the response body embedded in the message — Braintrust's error JSON names the exact problem
Defensive patterns
Strategy: try-catch
Validate before calling
import httpx, os
def braintrust_key_ok() -> bool:
try:
r = httpx.get("https://api.braintrust.dev/v1/project",
headers={"Authorization": f"Bearer {os.getenv('BRAINTRUST_API_KEY','')}"},
timeout=5)
return r.status_code < 400
except httpx.RequestError:
return False Try / catch
try:
project_id = logger.get_project_id_sync(project_name)
except Exception as e:
# message body distinguishes auth (401) vs payload (4xx); restart clears the per-process cache
raise RuntimeError(f"braintrust project registration failed: {e}") from e Prevention
- Smoke-test the key against the Braintrust API during deploy
- Restart the process after rotating BRAINTRUST_API_KEY to reset _project_id_cache
- Use plain project names (alphanumerics/dashes)
When it happens
Trigger: First sync-logged event for a project when BRAINTRUST_API_KEY is invalid/expired (401), lacks permission (403), or the project name is rejected (4xx). Subsequent calls hit the cache and do not re-raise unless the process restarts.
Common situations: Rotated API keys not updated in the proxy env; org-scoped keys without access to the target project; project names with characters Braintrust rejects; pointing api_base at a wrong/proxied endpoint.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- {e.response.text}
- Error listing files in '{directory_path}': {e}
- Failed to get repository info: {e}
- Failed to get branches: {e}
- Failed to get file metadata for '{file_path}': {e}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/c6b242c76db06da5.
Report an issue: GitHub.