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
- 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.