BerriAI/litellm · error · ValueError

usage object and custom_llm_provider must be provided for re

Error message

usage object and custom_llm_provider must be provided for realtime stream cost calculation. Got cost_per_token_usage_object={cost_per_token_usage_object}, custom_llm_provider={custom_llm_provider}

What it means

Realtime API streams (call_type 'arealtime') are priced from an aggregated usage object plus the provider name. If cost_per_token_usage_object or custom_llm_provider is None when completion_cost is called on a LiteLLMRealtimeStreamLoggingObject, LiteLLM raises ValueError because per-token realtime pricing cannot be resolved without both.

Source

Thrown at litellm/cost_calculator.py:1497

                        completion_tokens_cost_usd_dollar=completion_cost_result,
                        cost_for_built_in_tools_cost_usd_dollar=0.0,
                        total_cost_usd_dollar=_final_cost,
                        original_cost=original_cost,
                        discount_percent=discount_percent,
                        discount_amount=discount_amount,
                        margin_percent=margin_percent,
                        margin_fixed_amount=margin_fixed_amount,
                        margin_total_amount=margin_total_amount,
                        service_tier=service_tier,
                        data_residency=data_residency,
                    )

                    return _final_cost
                elif call_type == _AREALTIME_CALL_TYPE and isinstance(
                    completion_response, LiteLLMRealtimeStreamLoggingObject
                ):
                    if cost_per_token_usage_object is None or custom_llm_provider is None:
                        raise ValueError(
                            f"usage object and custom_llm_provider must be provided for realtime stream cost calculation. Got cost_per_token_usage_object={cost_per_token_usage_object}, custom_llm_provider={custom_llm_provider}"
                        )
                    return handle_realtime_stream_cost_calculation(
                        results=completion_response.results,
                        combined_usage_object=cost_per_token_usage_object,
                        custom_llm_provider=custom_llm_provider,
                        litellm_model_name=model,
                        data_residency=data_residency,
                        litellm_logging_obj=litellm_logging_obj,
                    )
                elif call_type == _MCP_CALL_TYPE:
                    from litellm.proxy._experimental.mcp_server.cost_calculator import (
                        MCPCostCalculator,
                    )

                    return MCPCostCalculator.calculate_mcp_tool_call_cost(litellm_logging_obj=litellm_logging_obj)
                # Calculate cost based on prompt_tokens, completion_tokens
                if "togethercomputer" in model or "together_ai" in model or custom_llm_provider == "together_ai":

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Pass both arguments: completion_cost(..., cost_per_token_usage_object=aggregated_usage, custom_llm_provider='openai').
  2. Let LiteLLM's default logging handle realtime cost — extend via custom callback reading kwargs['response_cost'] instead of recomputing.
  3. Aggregate usage across the realtime stream (input_tokens/output_tokens) before computing cost.
  4. Update LiteLLM if an older version didn't populate these fields for realtime.

Example fix

# before
cost = litellm.completion_cost(
    completion_response=realtime_obj, call_type="arealtime",
)

# after
combined = Usage(prompt_tokens=p_in, completion_tokens=p_out)
cost = litellm.completion_cost(
    completion_response=realtime_obj, call_type="arealtime",
    cost_per_token_usage_object=combined,
    custom_llm_provider="openai",
)
Defensive patterns

Strategy: validation

Validate before calling

if call_type == "arealtime":
    assert cost_per_token_usage_object is not None, "aggregate realtime usage before cost calc"
    assert custom_llm_provider is not None, "provider required for realtime pricing"

Type guard

def realtime_cost_ready(usage_obj, provider: str | None) -> bool:
    return usage_obj is not None and provider is not None

Try / catch

try:
    cost = litellm.completion_cost(
        completion_response=realtime_obj, call_type="arealtime",
        cost_per_token_usage_object=combined_usage, custom_llm_provider="openai",
    )
except ValueError as e:
    if "realtime stream cost calculation" in str(e):
        cost = None  # recompute after aggregating usage
    else:
        raise

Prevention

When it happens

Trigger: Calling completion_cost(call_type='arealtime', completion_response=realtime_stream_obj) without passing cost_per_token_usage_object and custom_llm_provider; usually hit in custom logging callbacks that replicate LiteLLM's cost step manually.

Common situations: Custom success handlers on the proxy that call completion_cost with only the response; realtime sessions where usage aggregation was skipped; version changes that introduced the cost_per_token_usage_object parameter.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/5ec78acd5c1ce9a2. Report an issue: GitHub.