BerriAI/litellm · error · HTTPException
project_id is required
Error message
project_id is required
What it means
PUT /project/update requires project_id to identify the record to modify; the field is optional on the Pydantic model, so a missing/null value is caught explicitly and rejected with HTTP 400 before the database fetch. Unlike creation, no id is ever generated on update.
Source
Thrown at enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py:555
# ADD METADATA FIELDS
for field in LiteLLM_ManagementEndpoint_MetadataFields_Premium:
if getattr(data, field, None) is not None:
_set_object_metadata_field(
object_data=data,
field_name=field,
value=getattr(data, field),
)
delattr(data, field)
if prisma_client is None:
raise HTTPException(
status_code=500,
detail={"error": CommonProxyErrors.db_not_connected_error.value},
)
if data.project_id is None:
raise HTTPException(
status_code=400,
detail={"error": "project_id is required"},
)
# Fetch existing project
existing_project: (
prisma_models.LiteLLM_ProjectTable | None
) = await prisma_client.db.litellm_projecttable.find_unique(where={"project_id": data.project_id})
if existing_project is None:
raise ProxyException(
message=f"Project not found, project_id={data.project_id}",
type="not_found",
code=404,
param="project_id",
)
# Permission to *edit* the project must be evaluated against theView on GitHub (pinned to 6c2dcb801b)
Solutions
- Include the existing project_id in the update payload
- If you do not know the id, list projects first (e.g. GET /project/list) to find it
- Distinguish create vs update flows in client code: update always needs the id
Example fix
// before
{"max_budget": 100}
// after
{"project_id": "project-123", "max_budget": 100} Defensive patterns
Strategy: type-guard
Validate before calling
if not payload.get('project_id'):
raise ValueError('PUT /project/update requires project_id; fetch it via GET /project/list') Type guard
const isUpdatePayload = (p): p is { project_id: string } =>
typeof p.project_id === 'string' && p.project_id.length > 0; Prevention
- Use distinct types/functions for create vs update payloads in client code
- Bind update forms to the id fetched from list endpoints, never free-text input
When it happens
Trigger: PUT /project/update with a body that omits project_id or sends it as null, e.g. only {"max_budget": 100}.
Common situations: Reusing a creation payload template for updates, frontend form not binding the id field, or stripping ids during JSON sanitization.
Related errors
- soft_budget cannot be negative. Received: {data.soft_budget}
- soft_budget ({data.soft_budget}) must be strictly lower than
- Model '{m}' not in team's allowed models. Team allowed model
- Project max_budget ({data.max_budget}) exceeds team's max_bu
- Project tpm_limit ({data.tpm_limit}) exceeds team's tpm_limi
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/d8877341ca4afbcd.
Report an issue: GitHub.