BerriAI/litellm · error · HTTPException
Failed to update cost discount config: {e}
Error message
Failed to update cost discount config: {e} What it means
Catch-all HTTP 500 from PATCH /config/cost_discount_config: after all validation passed, the endpoint loads the config via proxy_config.get_config(), mutates litellm_settings, saves back to the DB, and updates litellm.cost_discount_config in memory; if any of those steps raises, the exception is logged ('Error updating cost discount config') and re-raised wrapped in this message with the original error text.
Source
Thrown at litellm/proxy/management_endpoints/cost_tracking_settings.py:262
# Update cost_discount_config
config["litellm_settings"]["cost_discount_config"] = cost_discount_config
# Save the updated config to DB
await proxy_config.save_config(new_config=config)
# Update in-memory litellm.cost_discount_config
litellm.cost_discount_config = cost_discount_config
verbose_proxy_logger.info("Updated cost_discount_config: %s", cost_discount_config)
return {
"message": "Cost discount configuration updated successfully",
"status": "success",
"values": cost_discount_config,
}
except Exception as e:
verbose_proxy_logger.error("Error updating cost discount config: %s", e)
raise HTTPException(
status_code=500,
detail={"error": f"Failed to update cost discount config: {e}"},
)
@router.get(
"/config/cost_margin_config",
tags=["Cost Tracking"],
dependencies=[Depends(user_api_key_auth)],
)
async def get_cost_margin_config(
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
):
"""
Get current cost margin configuration.
Returns the cost_margin_config from litellm_settings.
"""View on GitHub (pinned to 77b7c6c40c)
Solutions
- Read the appended original exception ({e}) in the response and the verbose_proxy_logger line — it names the real cause.
- If it is a DB error, verify PostgreSQL health/connectivity and retry the PATCH.
- Inspect the stored config row (config table / GET /config/list) for corruption and repair it before re-applying.
- Retry once after the transient condition clears; the update is not applied if the exception occurred before save.
Defensive patterns
Strategy: try-catch
Try / catch
try:
r = requests.patch(f"{PROXY_URL}/config/cost_discount_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 discount config" in detail:
log.error("proxy-side failure: %s", detail) # detail embeds the root cause
verify_state_with_get() # confirm old config still active, then decide retry
else:
raise Prevention
- Treat the 500 detail's embedded exception as the diagnosis — parse and log it.
- Confirm DB health before retrying; the failure is usually persistence-side.
- Fetch GET /config/cost_discount_config after any 500 to know the actual applied state.
When it happens
Trigger: Prisma errors while writing the config row (DB restarted mid-request, connection dropped, permissions); malformed existing config in DB causing serialization/merge failures; transient failures in proxy_config.save_config.
Common situations: Database connectivity blips during the write; a previously corrupted config JSON in the config table; concurrent config mutations racing each other.
Related errors
- Failed to update cost margin 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/121bd5c0f13fa85a.
Report an issue: GitHub.