BerriAI/litellm · error · ValueError
otel.attributes: {TOKEN_TYPE_ATTRIBUTE} is a structural toke
Error message
otel.attributes: {TOKEN_TYPE_ATTRIBUTE} is a structural token-usage discriminator and cannot be filtered What it means
The token_type attribute (TOKEN_TYPE_ATTRIBUTE) is the structural discriminator LiteLLM's OTEL exporter uses to distinguish prompt/completion/cache token dimensions in token-usage metrics. Filtering it (via an exclude_list naming it, or any requested list containing it) would corrupt the metric shape, so _resolve_metric_attribute_filter explicitly rejects it.
Source
Thrown at litellm/integrations/opentelemetry.py:182
)
return OTELMetricAttributeFilter(
include_list=value.get("include_list"),
exclude_list=value.get("exclude_list"),
)
def _resolve_metric_attribute_filter(
attributes: OTELMetricAttributeFilter | None,
) -> tuple[frozenset[str] | None, frozenset[str] | None]:
if attributes is None:
return None, None
include: Final = attributes.include_list or None
exclude: Final = attributes.exclude_list or None
if include and exclude:
raise ValueError("otel.attributes: include_list and exclude_list are mutually exclusive")
requested: Final = include or exclude or []
if TOKEN_TYPE_ATTRIBUTE in requested:
raise ValueError(
f"otel.attributes: {TOKEN_TYPE_ATTRIBUTE} is a structural token-usage discriminator and cannot be filtered"
)
unknown: Final = sorted(name for name in requested if name not in VALID_METRIC_ATTRIBUTE_NAMES)
if unknown:
raise ValueError(
f"otel.attributes: unknown attribute name(s) {unknown}. Valid names: {sorted(VALID_METRIC_ATTRIBUTE_NAMES)}"
)
return (
frozenset(include) if include else None,
frozenset(exclude) if exclude else None,
)
def _normalize_team_metadata_keys(value: Any) -> list[str]:
"""Coerce a team-metadata allowlist from a list or comma-separated string.
config.yaml passes a YAML list; an env var passes a comma-separated string.
Both collapse to a list of stripped, non-empty keys.View on GitHub (pinned to 6c2dcb801b)
Solutions
- Remove the token_type attribute name from exclude_list
- If using include_list, keep token_type in the allowed set (or switch to exclude_list for everything else you want dropped)
- Reduce cardinality by filtering other attributes instead (see VALID_METRIC_ATTRIBUTE_NAMES in the error's sibling validation)
- Keep config aligned with the installed litellm version's valid-name list shown in the unknown-attribute error
Example fix
# before
otel:
attributes:
exclude_list: [litellm_token_type_attribute] # ValueError: structural discriminator
# after
otel:
attributes:
exclude_list: [end_user, api_key_hash] # filter non-structural attributes only Defensive patterns
Strategy: validation
Validate before calling
TOKEN_TYPE_ATTRIBUTE = "litellm_token_type_attribute" # match the installed version's constant
VALID = {"model", "end_user", "api_key_hash", "api_provider"} # extend from your litellm version
def validate_otel_filter(attrs: dict) -> None:
requested = set(attrs.get("include_list") or []) | set(attrs.get("exclude_list") or [])
if TOKEN_TYPE_ATTRIBUTE in requested:
raise ValueError(f"{TOKEN_TYPE_ATTRIBUTE} cannot be filtered")
unknown = requested - VALID
if unknown:
raise ValueError(f"unknown attributes: {sorted(unknown)}") Prevention
- Read the error message for the exact valid attribute-name list on your litellm version
- Treat structural metric labels as untouchable when trimming cardinality
When it happens
Trigger: exclude_list containing the token_type attribute name; an include_list or exclude_list that includes it; copy-pasting an allow-list of common label names that happens to include it while trimming metric cardinality.
Common situations: Operators trying to reduce metric cardinality by trimming attributes and targeting token_type as 'just another label'; migrating from older litellm versions where this attribute was filterable.
Related errors
- otel.attributes must be a mapping with optional 'include_lis
- otel.attributes: include_list and exclude_list are mutually
- duration needs to be one of ["daily", "weekly", "monthly", "
- LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY must be set for
- Invalid mode: {custom_auth_settings['mode']}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/1f10363ca0dbc15f.
Report an issue: GitHub.