{"record":{"id":"8c1bd03028f68c03","repo":"BerriAI/litellm","slug":"soft-budget-data-soft-budget-must-be-strictly","errorCode":null,"errorMessage":"soft_budget ({data.soft_budget}) must be strictly lower than max_budget ({data.max_budget})","messagePattern":"soft_budget \\((.+?)\\) must be strictly lower than max_budget \\((.+?)\\)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py","lineNumber":156,"sourceCode":"    - Budget values are non-negative\n    - soft_budget < max_budget\n    \"\"\"\n    # --- Budget non-negativity checks ---\n    if data.max_budget is not None and data.max_budget < 0:\n        raise HTTPException(\n            status_code=400,\n            detail={\"error\": f\"max_budget cannot be negative. Received: {data.max_budget}\"},\n        )\n    if data.soft_budget is not None and data.soft_budget < 0:\n        raise HTTPException(\n            status_code=400,\n            detail={\"error\": f\"soft_budget cannot be negative. Received: {data.soft_budget}\"},\n        )\n\n    # --- soft_budget < max_budget ---\n    if data.soft_budget is not None and data.max_budget is not None:\n        if data.soft_budget >= data.max_budget:\n            raise HTTPException(\n                status_code=400,\n                detail={\n                    \"error\": f\"soft_budget ({data.soft_budget}) must be strictly lower than max_budget ({data.max_budget})\"\n                },\n            )\n\n    # --- Validate project models are a subset of team models ---\n    project_models = data.models\n    team_models: list[str] = team_object.models or []\n    if project_models and len(team_models) > 0:\n        # If team has 'all-proxy-models', skip validation as it allows all models\n        if SpecialModelNames.all_proxy_models.value not in team_models:\n            for m in project_models:\n                if m not in team_models:\n                    raise HTTPException(\n                        status_code=400,\n                        detail={\n                            \"error\": f\"Model '{m}' not in team's allowed models. Team allowed models={team_models}. Team: {team_object.team_id}\"","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py#L138-L174","documentation":"Cross-field rule in _check_team_project_limits: when both soft_budget and max_budget are set, soft_budget must be strictly lower; equal or greater values return HTTP 400 with both numbers. soft_budget is meant as an alert threshold before the hard cap.","triggerScenarios":"POST/PUT project with soft_budget equal to max_budget (e.g. both 100) or soft_budget above max_budget.","commonSituations":"Configs written with soft == max intending 'alert exactly at the cap'; templates that copy the same number into both fields; defaults regenerated without scaling.","solutions":["Set soft_budget strictly below max_budget (e.g. 80% of it)","Omit soft_budget if no early-warning threshold is needed","Generate soft_budget programmatically as max_budget * 0.8"],"exampleFix":"# before\n{\"max_budget\": 100, \"soft_budget\": 100}\n\n# after\n{\"max_budget\": 100, \"soft_budget\": 80}","handlingStrategy":"validation","validationCode":"def validate_budget_pair(data: dict) -> dict:\n    sb, mb = data.get(\"soft_budget\"), data.get(\"max_budget\")\n    if sb is not None and mb is not None and sb >= mb:\n        raise ValueError(f\"soft_budget ({sb}) must be strictly lower than max_budget ({mb})\")\n    return data","typeGuard":null,"tryCatchPattern":"try:\n    await post(\"/project/new\", json=data)\nexcept HTTPStatusError as e:\n    if e.response.status_code == 400 and \"strictly lower\" in e.response.text:\n        data[\"soft_budget\"] = data[\"max_budget\"] * 0.8\n        retry()\n    raise","preventionTips":["Derive soft_budget from max_budget (e.g. 80%) in config generators","Never copy the same number into both budget fields"],"tags":["litellm","projects","budget","validation","http-400"],"backgroundTag":"request-validation-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}