BerriAI/litellm · error · HTTPException
soft_budget ({data.soft_budget}) must be strictly lower than
Error message
soft_budget ({data.soft_budget}) must be strictly lower than max_budget ({data.max_budget}) What it means
LiteLLM enforces that a project's soft_budget (alert threshold) is strictly lower than its max_budget (hard cap). If both are provided and soft_budget >= max_budget, the request is rejected with HTTP 400 before any DB write, because an alert threshold at or above the hard limit could never fire usefully.
Source
Thrown at enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py:131
- 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 = team_object.models or []
if project_models and len(team_models) > 0:
# If team has 'all-proxy-models', skip validation as it allows all models
if SpecialModelNames.all_proxy_models.value not in team_models:
for m in project_models:
if m not in team_models:
raise HTTPException(
status_code=400,
detail={
"error": f"Model '{m}' not in team's allowed models. Team allowed models={team_models}. Team: {team_object.team_id}"View on GitHub (pinned to 6c2dcb801b)
Solutions
- Set soft_budget strictly below max_budget (e.g. 80% of max_budget)
- If you swapped the fields, exchange the values and retry
- Omit soft_budget (null) if you do not want threshold alerts
Example fix
// before
{"max_budget": 100, "soft_budget": 100}
// after
{"max_budget": 100, "soft_budget": 80} Defensive patterns
Strategy: validation
Validate before calling
def check_budgets(p):
sb, mb = p.get('soft_budget'), p.get('max_budget')
if sb is not None and mb is not None and sb >= mb:
p['soft_budget'] = round(mb * 0.8, 2) # or raise ValueError locally Type guard
const budgetsConsistent = (p) => p.soft_budget == null || p.max_budget == null || p.soft_budget < p.max_budget;
Try / catch
catch (e) {
if (e.status === 400 && /soft_budget.*strictly lower/.test(e.body?.detail?.error ?? '')) {
body.soft_budget = body.max_budget * 0.8; return retry(body);
}
throw e;
} Prevention
- Always derive soft_budget as a fraction (e.g. 80%) of max_budget instead of hardcoding both
- Add a pre-flight assert soft < max in CI config validation
When it happens
Trigger: POST /project/new or PUT /project/update with both soft_budget and max_budget set where soft_budget >= max_budget, e.g. soft_budget=100 and max_budget=100 (equality also fails; the check is >=).
Common situations: Setting the two budgets to the same round number, swapping the fields by mistake, or scaling one budget without scaling the other during a config migration.
Related errors
- soft_budget cannot be negative. Received: {data.soft_budget}
- Project max_budget ({data.max_budget}) exceeds team's max_bu
- Model '{m}' not in team's allowed models. Team allowed model
- Project tpm_limit ({data.tpm_limit}) exceeds team's tpm_limi
- Project rpm_limit ({data.rpm_limit}) exceeds team's rpm_limi
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/8c1bd03028f68c03.
Report an issue: GitHub.