BerriAI/litellm · error · HTTPException

team_id is required when PTU fields are set (one model maps

Error message

team_id is required when PTU fields are set (one model maps to one team)

What it means

Attribution guard on PTU model_info: PTU count/rate fields are set but no team_id is present. PTU billing maps one model to exactly one owning team, so without team_id the flat cost cannot be attributed; rejected with 400 at write time.

Source

Thrown at litellm/proxy/management_endpoints/model_management_endpoints.py:340

        raise HTTPException(status_code=400, detail="ptu_effective_to must be after ptu_effective_from")

    has_count: Final = model_info.get("ptu_count") is not None
    has_rate: Final = model_info.get("cost_per_ptu_per_hour") is not None
    if not has_count and not has_rate:
        return
    if has_count != has_rate:
        raise HTTPException(status_code=400, detail="ptu_count and cost_per_ptu_per_hour must be set together")
    if effective_from is None:
        raise HTTPException(
            status_code=400,
            detail=(
                "ptu_effective_from is required when PTU fields are set. Flat cost accrues from that "
                "instant, so without it the start would have to be inferred and a deployment configured "
                "today could be billed for days it did not exist"
            ),
        )
    if not model_info.get("team_id"):
        raise HTTPException(
            status_code=400, detail="team_id is required when PTU fields are set (one model maps to one team)"
        )


# The mirrored per-token pricing fields plus the three remaining fields
# Router._inherit_builtin_cache_pricing back-fills from the public cost map. An unset field is
# what that back-fill targets, so a field left out here is one a PTU deployment still bills.
# tiered_pricing is the one mirrored field that is a table of ranges, not a rate, so it is stored
# empty (see _PTU_EMPTIED_PRICING_FIELDS): its tiers outrank the zeros written beside them, so
# dropping it would leave the cost map's tiers billing the traffic the reserved capacity covers.
_PTU_ZEROED_PRICING_FIELDS: Final = tuple(f for f in SPECIAL_MODEL_INFO_PARAMS if f != "tiered_pricing") + (
    "cache_creation_input_token_cost_above_1hr",
    "cache_creation_input_token_cost_above_200k_tokens",
    "cache_read_input_token_cost_above_200k_tokens",
)
_PTU_EMPTIED_PRICING_FIELDS: Final = frozenset({"tiered_pricing"})
_PTU_ZEROED_PRICING: Final[Mapping[str, float | tuple[()]]] = MappingProxyType(
    {

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Provide team_id in model_info when setting PTU fields.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at litellm/proxy/management_endpoints/model_management_endpoints.py:340 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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