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_config

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. To zero out a margin, send {"openai": 0} or remove the key from the payload.
  2. Ensure dict values contain at least one of 'percentage' or 'fixed_amount', spelled exactly.
  3. 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

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


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/b69d64083dcb517d. Report an issue: GitHub.