BerriAI/litellm · error · ValueError
unknown mapper name ; known
Error message
unknown mapper name {name!r}; known: {known} What it means
The OTel v2 callback resolves its attribute vocabularies by name via resolve_mappers(). Valid names are genai, legacy, and openinference (tool-definition mappers) plus langfuse, weave, and langtrace (plain mappers); any other entry raises ValueError with the unknown name and the sorted list of known names. The config key feeding this is mapper_names in the OpenTelemetry v2 config (config.mapper_names), which layers semantic-convention vocabularies onto each span.
Solutions
- Use exactly one of the known names: genai, legacy, openinference, langfuse, weave, langtrace — all lowercase
- Fix the common typo: openai -> openinference when you want Arize/Phoenix attribute keys
- If a documented name is reported unknown, upgrade litellm — newer releases added mappers (weave, langtrace)
- Rely on the error's sorted known-list rather than memory when editing the config
Example fix
# before mapper_names: ["genai", "openai"] # after mapper_names: ["genai", "openinference"]
Defensive patterns
Strategy: type-guard
Validate before calling
KNOWN_MAPPERS = {'genai', 'legacy', 'openinference', 'langfuse', 'weave', 'langtrace'}
names = cfg['otel'].get('mapper_names', [])
unknown = [n for n in names if n not in KNOWN_MAPPERS]
if unknown:
raise SystemExit(f'unknown mapper_names {unknown}; known: {sorted(KNOWN_MAPPERS)}') Type guard
def is_known_mapper(name: str) -> bool:
"""True when name is a resolvable OTel v2 attribute vocabulary."""
return name in {'genai', 'legacy', 'openinference', 'langfuse', 'weave', 'langtrace'} Try / catch
try:
from litellm.integrations.otel.mappers import resolve_mappers
mappers = resolve_mappers(names)
except ValueError as e:
if 'unknown mapper name' in str(e):
raise ConfigError(f'fix mapper_names: {e}') from e
raise Prevention
- Use the error's printed known-list as the source of truth for the installed version
- Remember vendor name != mapper name: Arize/Phoenix coverage comes from 'openinference', not 'arize'/'phoenix'/'openai'
- Mapper names are lowercase and exact — 'Langfuse' fails
- Re-run a resolve_mappers smoke test in CI whenever mapper_names or the litellm version changes
When it happens
Trigger: Configuring the v2 OTel callback with a misspelled or unsupported vocabulary, e.g. mapper_names: [genai, openai] (openai is not a mapper — the Arize/Phoenix vocabulary is openinference), or pluralized/case-sensitive variants like Langfuse or weaves. Resolution happens when the logger builds, so it fails at startup or first use of the callback.
Common situations: Assuming the vendor name matches the mapper name (openai, arize, phoenix are all invalid; openinference covers Arize/Phoenix); case mismatch (Langfuse vs langfuse — lookup is exact); stale docs or examples from a version before new mappers were added (e.g. weave/langtrace missing in an older install, so a valid-in-docs name is unknown in the installed release).
Related errors
- otel.attributes: include_list and exclude_list are mutually…
- otel.attributes: is a structural token-usage discriminator…
- otel.attributes: unknown attribute name(s)
- OpenTelemetry OTLP gRPC log exporter is not available…
- OpenTelemetry OTLP gRPC metric exporter is not available…
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/ac598a45047aa82a.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/integrations/otel/mappers/__init__.py:47
_TOOL_DEFINITION_MAPPERS: Final[dict[str, Callable[[int], AttributeMapper]]] = {
"genai": GenAIMapper,
"legacy": LegacyMapper,
"openinference": OpenInferenceMapper,
}
_PLAIN_MAPPERS: Final[dict[str, Callable[[], AttributeMapper]]] = {
"langfuse": LangfuseMapper,
"weave": WeaveMapper,
"langtrace": LangtraceMapper,
}
def resolve_mappers(names: Iterable[str]) -> list[AttributeMapper]:
"""Resolve mapper names to instances. Unknown names raise ``ValueError``."""
ordered: Final = tuple(names)
for name in ordered:
if name not in _TOOL_DEFINITION_MAPPERS and name not in _PLAIN_MAPPERS:
known = sorted((*_TOOL_DEFINITION_MAPPERS, *_PLAIN_MAPPERS))
raise ValueError(f"unknown mapper name {name!r}; known: {known}")
# Distinct vocabularies each write the tool family under their own keys, so
# the ceiling is split by how many of them are configured. Repeating a name
# rewrites the same keys, so only distinct ones count.
budget: Final = tool_attr_budget(len({*ordered} & _TOOL_DEFINITION_MAPPERS.keys()))
return [
_TOOL_DEFINITION_MAPPERS[name](budget) if name in _TOOL_DEFINITION_MAPPERS else _PLAIN_MAPPERS[name]()
for name in ordered
]
__all__ = [
"AttrValue",
"AttributeMap",
"AttributeMapper",
"GenAIMapper",
"LangfuseMapper",
"LangtraceMapper",
"LegacyMapper",View on GitHub (pinned to 77b7c6c40c)