{"record":{"id":"1313bc453ef9b0d2","repo":"BerriAI/litellm","slug":"otel-attributes-unknown-attribute-name-s-unknow","errorCode":null,"errorMessage":"otel.attributes: unknown attribute name(s) {unknown}. Valid names: {sorted(VALID_METRIC_ATTRIBUTE_NAMES)}","messagePattern":"otel\\.attributes: unknown attribute name\\(s\\) (.+?)\\. Valid names: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/opentelemetry.py","lineNumber":187,"sourceCode":"\n\ndef _resolve_metric_attribute_filter(\n    attributes: OTELMetricAttributeFilter | None,\n) -> tuple[frozenset[str] | None, frozenset[str] | None]:\n    if attributes is None:\n        return None, None\n    include: Final = attributes.include_list or None\n    exclude: Final = attributes.exclude_list or None\n    if include and exclude:\n        raise ValueError(\"otel.attributes: include_list and exclude_list are mutually exclusive\")\n    requested: Final = include or exclude or []\n    if TOKEN_TYPE_ATTRIBUTE in requested:\n        raise ValueError(\n            f\"otel.attributes: {TOKEN_TYPE_ATTRIBUTE} is a structural token-usage discriminator and cannot be filtered\"\n        )\n    unknown: Final = sorted(name for name in requested if name not in VALID_METRIC_ATTRIBUTE_NAMES)\n    if unknown:\n        raise ValueError(\n            f\"otel.attributes: unknown attribute name(s) {unknown}. Valid names: {sorted(VALID_METRIC_ATTRIBUTE_NAMES)}\"\n        )\n    return (\n        frozenset(include) if include else None,\n        frozenset(exclude) if exclude else None,\n    )\n\n\ndef _normalize_team_metadata_keys(value: Any) -> list[str]:\n    \"\"\"Coerce a team-metadata allowlist from a list or comma-separated string.\n\n    config.yaml passes a YAML list; an env var passes a comma-separated string.\n    Both collapse to a list of stripped, non-empty keys.\n    \"\"\"\n    if value is None:\n        return []\n    if isinstance(value, str):\n        return [item.strip() for item in value.split(\",\") if item.strip()]","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/opentelemetry.py#L169-L205","documentation":"The otel.attributes filter is allowlist-based: every name in include_list/exclude_list must be one of the recognized metric attributes. The valid set is gen_ai.operation.name, gen_ai.provider.name, gen_ai.system, gen_ai.request.model, gen_ai.framework, hidden_params, and metadata.<key> for each supported metadata key (user_api_key_hash, user_api_key_alias, user_api_key_team_id, user_api_key_org_id, user_api_key_user_id, user_api_key_team_alias, user_api_key_user_email, spend_logs_metadata, requester_ip_address, requester_metadata, user_api_key_end_user_id, prompt_management_metadata, applied_guardrails, mcp_tool_call_metadata, vector_store_request_metadata). Unknown names raise ValueError listing both the offenders and the sorted valid set.","triggerScenarios":"Typing an attribute name wrong (gen_ai.request.model vs gen_ai.request_model, or gen_ai.response.model which is not in the metric set), inventing plausible names (gen_ai.token.type aside, e.g. gen_ai.usage.tokens), or using metadata.X where X is not one of the supported metadata keys. Validated eagerly for explicit config, or on first metric record for proxy callback_settings.","commonSituations":"Copying span attribute names (a much larger vocabulary) into the metric filter config; version skew where an older litellm emitted names no longer in the valid set (or vice versa: docs newer than the installed version); renaming drift between gen_ai semconv versions (e.g. gen_ai.system.identity vs gen_ai.system).","solutions":["Read the error: it prints the exact unknown names and the full sorted valid list for your installed version","Fix typos/rename to a valid name — most intents map to gen_ai.request.model, gen_ai.system, gen_ai.provider.name, etc.","For metadata-type attributes, use the exact metadata.<key> spelling from the valid list (e.g. metadata.user_api_key_team_id)","If a name you expect is missing from the valid list, upgrade litellm — the allowlist may have gained entries in a newer release"],"exampleFix":"# before\nattributes:\n  include_list: [gen_ai.request_model, gen_ai.system]\n# after\nattributes:\n  include_list: [gen_ai.request.model, gen_ai.system]","handlingStrategy":"validation","validationCode":"METADATA_KEYS = {'user_api_key_hash','user_api_key_alias','user_api_key_team_id','user_api_key_org_id','user_api_key_user_id','user_api_key_team_alias','user_api_key_user_email','spend_logs_metadata','requester_ip_address','requester_metadata','user_api_key_end_user_id','prompt_management_metadata','applied_guardrails','mcp_tool_call_metadata','vector_store_request_metadata'}\nBASE = {'gen_ai.operation.name','gen_ai.provider.name','gen_ai.system','gen_ai.request.model','gen_ai.framework','hidden_params'}\nVALID = BASE | {f'metadata.{k}' for k in METADATA_KEYS}\n\nattrs = config['otel'].get('attributes') or {}\nrequested = (attrs.get('include_list') or []) + (attrs.get('exclude_list') or [])\nunknown = sorted(set(requested) - VALID)\nif unknown:\n    raise SystemExit(f'unknown otel.attributes names {unknown}; valid: {sorted(VALID)}')","typeGuard":"def known_metric_attributes(names: list[str]) -> list[str]:\n    \"\"\"Return the subset of names that are valid metric attribute filters.\"\"\"\n    return [n for n in names if n in VALID]  # VALID built as above","tryCatchPattern":"try:\n    otel_cb = OpenTelemetry(attributes=attrs)\nexcept ValueError as e:\n    if 'unknown attribute name' in str(e):\n        # the message prints valid names for the INSTALLED version; reconcile config to it\n        raise ConfigError(f'fix otel.attributes names: {e}') from e\n    raise","preventionTips":["Source filter name lists from the error output of the installed version, not from memory or newer docs","Pin the litellm version and keep a reviewed snapshot of the valid attribute set beside your config","Add a CI config test that constructs OpenTelemetry(attributes=...) to validate before deploy","Distinguish span attributes from metric attributes in internal docs to stop vocabulary bleed"],"tags":["opentelemetry","otel","configuration","metrics","allowlist","validation"],"backgroundTag":"unknown-config-key","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}