BerriAI/litellm · warning · HTTPException
Margin config for {provider} cannot be empty. Must include '
Error message
Margin config for {provider} cannot be empty. Must include 'percentage' and/or 'fixed_amount' What it means
Validation error (HTTP 400) from PATCH /config/cost_margin_config: a provider's margin value is a dict but contains neither 'percentage' nor 'fixed_amount' (e.g. {} or {"foo": 1}). The dict format exists solely to carry those two optional keys, so an empty/irrelevant dict is rejected with a message telling you which keys are expected.
Source
Thrown at litellm/proxy/management_endpoints/cost_tracking_settings.py:400
if not (0 <= percentage <= 10):
raise HTTPException(
status_code=400,
detail=f"Margin percentage for {provider} must be between 0 and 10 (0% to 1000%)",
)
if "fixed_amount" in margin_value:
fixed_amount = margin_value["fixed_amount"]
if not isinstance(fixed_amount, (int, float)):
raise HTTPException(
status_code=400,
detail=f"Fixed margin amount for {provider} must be a number",
)
if fixed_amount < 0:
raise HTTPException(
status_code=400,
detail=f"Fixed margin amount for {provider} must be non-negative",
)
if not margin_value: # Empty dict
raise HTTPException(
status_code=400,
detail=f"Margin config for {provider} cannot be empty. Must include 'percentage' and/or 'fixed_amount'",
)
else:
raise HTTPException(
status_code=400,
detail=f"Margin for {provider} must be a number (percentage) or dict with 'percentage' and/or 'fixed_amount'",
)
try:
# Load existing config
config: Final = await proxy_config.get_config()
# Ensure litellm_settings exists
if "litellm_settings" not in config:
config["litellm_settings"] = {}
# Update cost_margin_configView on GitHub (pinned to 77b7c6c40c)
Solutions
- To zero out a margin, send {"openai": 0} or remove the key from the payload.
- Ensure dict values contain at least one of 'percentage' or 'fixed_amount', spelled exactly.
- Guard your payload builder against emitting empty dicts for optional fields.
Example fix
# before
{"openai": {}}
# after
{"openai": 0} Defensive patterns
Strategy: validation
Validate before calling
for provider, margin in cost_margin_config.items():
if isinstance(margin, dict) and not ({"percentage", "fixed_amount"} & set(margin)):
if margin == {}:
cost_margin_config[provider] = 0 # normalize 'reset' to zero-margin
else:
raise ValueError(f"{provider}: dict must contain 'percentage' and/or 'fixed_amount'") Type guard
def is_nonempty_margin_dict(m: dict) -> bool:
return isinstance(m, dict) and bool({"percentage", "fixed_amount"} & set(m)) Prevention
- Reset a margin by sending 0 or omitting the provider — never {}.
- Spell-check 'percentage' and 'fixed_amount'; typo'd keys make the dict effectively empty.
When it happens
Trigger: Sending {"openai": {}} to 'reset' a margin (use 0 or omit the provider instead); dicts with typo'd keys like {"pecentage": 0.1} that therefore contain neither recognized field.
Common situations: Attempting to clear a provider's margin via an empty object; key typos that silently change the dict's effective content; template engines emitting {} for missing values.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid provider(s): {', '.join(invalid_providers)}. Must be
- Discount for {provider} must be a number
- Discount for {provider} must be between 0 and 1 (0% to 100%)
- Invalid provider(s): {', '.join(invalid_providers)}. Must be
- Margin percentage for {provider} must be between 0 and 10 (0
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/b69d64083dcb517d.
Report an issue: GitHub.