BerriAI/litellm · error · HTTPException
Failed to update cost margin config: {e}
Error message
Failed to update cost margin config: {e} What it means
Catch-all HTTP 500 from PATCH /config/cost_margin_config: all validation passed, but the subsequent config load/save (proxy_config.get_config / save to DB) or the in-memory update (litellm.cost_margin_config = ...) raised. The original exception is logged as 'Error updating cost margin config' and embedded in the response detail so the real cause is visible.
Source
Thrown at litellm/proxy/management_endpoints/cost_tracking_settings.py:436
# Update cost_margin_config
config["litellm_settings"]["cost_margin_config"] = cost_margin_config
# Save the updated config to DB
await proxy_config.save_config(new_config=config)
# Update in-memory litellm.cost_margin_config
litellm.cost_margin_config = cost_margin_config
verbose_proxy_logger.info("Updated cost_margin_config: %s", cost_margin_config)
return {
"message": "Cost margin configuration updated successfully",
"status": "success",
"values": cost_margin_config,
}
except Exception as e:
verbose_proxy_logger.error("Error updating cost margin config: %s", e)
raise HTTPException(
status_code=500,
detail={"error": f"Failed to update cost margin config: {e}"},
)
@router.post(
"/cost/estimate",
tags=["Cost Tracking"],
dependencies=[Depends(user_api_key_auth)],
response_model=CostEstimateResponse,
)
async def estimate_cost(
request: CostEstimateRequest,
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
) -> CostEstimateResponse:
"""
Estimate cost for a given model and token counts.
View on GitHub (pinned to 77b7c6c40c)
Solutions
- Read the embedded {e} text — it carries the underlying exception and points at DB vs config parsing.
- Restore/verify DB connectivity, then retry the PATCH (failed saves leave the old config intact).
- Fetch GET /config/cost_margin_config (or the raw config) to confirm state before and after retries.
- If corruption is indicated, repair the stored config row and re-apply.
Defensive patterns
Strategy: try-catch
Try / catch
try:
r = requests.patch(f"{PROXY_URL}/config/cost_margin_config", json=payload, headers=HDRS, timeout=15)
r.raise_for_status()
except requests.HTTPError as e:
detail = e.response.json().get("detail", {}).get("error", "")
if e.response.status_code == 500 and "Failed to update cost margin config" in detail:
log.error("root cause from proxy: %s", detail)
current = requests.get(f"{PROXY_URL}/config/cost_margin_config", headers=HDRS).json()
decide_retry_or_alert(current) # state-aware recovery instead of blind retry
else:
raise Prevention
- Parse the embedded {e} to separate DB failures from config-parse failures.
- Verify applied state with a follow-up GET after any 500.
- Serialize config mutations (single writer) to avoid concurrent-update races.
When it happens
Trigger: Prisma write failures (DB restarted, connection pool exhausted, permissions) during save_config; corrupt existing config JSON causing merge errors; races with another concurrent config update.
Common situations: Transient DB outages at the moment of the PATCH; a config table row that was hand-edited and no longer parses; multiple operators/automation updating config simultaneously.
Related errors
- Failed to update cost discount config: {e}
- Error fetching cache settings: {e}
- Failed to fetch analytics: {e}
- internal_server_error
- DB not connected. This endpoint needs a database; set DATABA
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/c19b19518b2c0236.
Report an issue: GitHub.