BerriAI/litellm · error · HTTPException
soft_budget cannot be negative. Received
Error message
soft_budget cannot be negative. Received: {data.soft_budget} What it means
Companion check in _check_team_project_limits: soft_budget < 0 returns HTTP 400 with the received value. soft_budget is the early-warning threshold under max_budget, so negative values are rejected outright.
Solutions
- Omit soft_budget (null is allowed) or send a non-negative value
- If no early-warning threshold is wanted, leave soft_budget unset rather than negative
- Fix the client code that computes soft_budget so it clamps at 0 or omits
Example fix
# before
{"project_alias": "p1", "soft_budget": -5}
# after
{"project_alias": "p1", "soft_budget": 80} Defensive patterns
Strategy: validation
Validate before calling
def sanitize_project_payload(data: dict) -> dict:
sb = data.get("soft_budget")
if sb is not None and sb < 0:
raise ValueError(f"soft_budget must be >= 0, got {sb}")
return data Type guard
def is_valid_budget(v) -> bool:
return v is None or (isinstance(v, (int, float)) and not isinstance(v, bool) and v >= 0) Try / catch
try:
await post("/project/new", json=data)
except HTTPStatusError as e:
if e.response.status_code == 400 and "cannot be negative" in e.response.text:
data.pop("soft_budget", None) # unset instead of negative
retry()
raise Prevention
- Omit optional budget fields rather than sending sentinels
- Clamp computed thresholds at 0 before submitting
When it happens
Trigger: POST /project/new or /project/update with "soft_budget": -1 or any negative number.
Common situations: Same sentinel-value mistakes as max_budget: clients defaulting unset numbers to -1, or computed thresholds going negative after budget consumption.
Related errors
- max_budget cannot be negative. Received
- Project max_budget ( ) exceeds team's max_budget ( ). Team
- soft_budget ( ) must be strictly lower than max_budget ( )
- Model ' ' not in team's allowed models. Team allowed…
- project_id is required
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/a6233e05d071ec22.
Report an issue: GitHub.
Appendix: source
Thrown at enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py:148
Mirrors _check_org_team_limits() from team_endpoints.py.
Validates:
- Project models are a subset of Team models
- Project max_budget <= Team max_budget
- Project tpm_limit <= Team tpm_limit
- Project rpm_limit <= Team rpm_limit
- Budget values are non-negative
- soft_budget < max_budget
"""
# --- Budget non-negativity checks ---
if data.max_budget is not None and data.max_budget < 0:
raise HTTPException(
status_code=400,
detail={"error": f"max_budget cannot be negative. Received: {data.max_budget}"},
)
if data.soft_budget is not None and data.soft_budget < 0:
raise HTTPException(
status_code=400,
detail={"error": f"soft_budget cannot be negative. Received: {data.soft_budget}"},
)
# --- soft_budget < max_budget ---
if data.soft_budget is not None and data.max_budget is not None:
if data.soft_budget >= data.max_budget:
raise HTTPException(
status_code=400,
detail={
"error": f"soft_budget ({data.soft_budget}) must be strictly lower than max_budget ({data.max_budget})"
},
)
# --- Validate project models are a subset of team models ---
project_models = data.models
team_models: list[str] = team_object.models or []
if project_models and len(team_models) > 0:View on GitHub (pinned to 77b7c6c40c)