fix(otel): bound _prune_none recursion depth and allowlist it

This commit is contained in:
Devin AI 2026-07-12 08:24:34 +00:00
parent 09a192c092
commit bbf664c6a1
2 changed files with 8 additions and 10 deletions

View file

@ -113,19 +113,16 @@ METRIC_METADATA_KEYS: Tuple[str, ...] = (
)
def _prune_none(value: "AnyValue") -> "AnyValue":
"""Recursively drop ``None`` entries from dicts and lists.
_PRUNE_MAX_DEPTH = 16
The OTLP exporter encodes a log record's body as ``AnyValue``, which has no
representation for ``None`` and raises ``Invalid type NoneType`` on it. That
aborts the export and makes ``BatchLogRecordProcessor`` drop the whole batch,
so a content event carrying a ``None`` (e.g. a ``content=None`` assistant
message) is silently lost. Pruning ``None`` first keeps it (Issue #32996).
"""
def _prune_none(value: "AnyValue", _depth: int = 0) -> "AnyValue":
if _depth >= _PRUNE_MAX_DEPTH:
return safe_dumps(value)
if isinstance(value, dict):
return {key: _prune_none(val) for key, val in value.items() if val is not None}
return {key: _prune_none(val, _depth + 1) for key, val in value.items() if val is not None}
if isinstance(value, list):
return [_prune_none(item) for item in value if item is not None]
return [_prune_none(item, _depth + 1) for item in value if item is not None]
return value

View file

@ -53,6 +53,7 @@ IGNORE_FUNCTIONS = [
"resolve_oci_schema_anyof", # OCI: bounded by JSON-schema tree depth (no cycles possible in well-formed input).
"sanitize_oci_schema", # OCI: bounded by JSON-schema tree depth.
"_freeze_for_dedupe", # OTEL: max depth set (default 16, _FREEZE_MAX_DEPTH); fails closed by returning repr(value) at the cap.
"_prune_none", # OTEL: max depth set (default 16, _PRUNE_MAX_DEPTH); fails closed by returning safe_dumps(value) at the cap.
"apply_json_merge_patch", # max depth set (_MAX_MERGE_DEPTH=64); fails closed by raising ValueError at the cap.
"_filter_mcp_argument_value", # max depth set (DEFAULT_MAX_RECURSE_DEPTH); fails closed by blocking the MCP call at the cap.
]