mlflow/mlflow · error · TypeError
TraceData.from_dict() expects a dictionary. Got: {type(d).__
Error message
TraceData.from_dict() expects a dictionary. Got: {type(d).__name__} What it means
TypeError raised by the classmethod TraceData.from_dict when the argument is not a dict. from_dict expects a mapping containing at least a 'spans' key (default []).
Source
Thrown at mlflow/entities/trace_data.py:28
@dataclass
class TraceData:
"""A container object that holds the spans data of a trace.
Args:
spans: List of spans that are part of the trace.
"""
spans: list[Span] = field(default_factory=list)
# NB: Custom constructor to allow passing additional kwargs for backward compatibility for
# DBX agent evaluator. Once they migrates to trace V3 schema, we can remove this.
def __init__(self, spans: list[Span] | None = None, **kwargs):
self.spans = spans or []
@classmethod
def from_dict(cls, d):
if not isinstance(d, dict):
raise TypeError(f"TraceData.from_dict() expects a dictionary. Got: {type(d).__name__}")
return cls(spans=[Span.from_dict(span) for span in d.get("spans", [])])
def to_dict(self) -> dict[str, Any]:
return {"spans": [span.to_dict() for span in self.spans]}
# TODO: remove this property in 3.7.0
@property
@deprecated(since="3.6.0", alternative="trace.search_spans(name=...)")
def intermediate_outputs(self) -> dict[str, Any] | None:
"""
.. deprecated:: 3.6.0
Use `trace.search_spans(name=...)` to search for spans and get the outputs.
Returns intermediate outputs produced by the model or agent while handling the request.
There are mainly two flows to return intermediate outputs:
1. When a trace is generate by the `mlflow.log_trace` API,
return `intermediate_outputs` attribute of the span.
2. When a trace is created normally with a tree of spans,View on GitHub (pinned to 6a27f2decc)
Solutions
- Parse JSON first: TraceData.from_dict(json.loads(s)) instead of passing the raw string
- Wrap non-dict payloads: if isinstance(d, str): d = json.loads(d)
- Ensure the JSON file has a top-level object like {"spans": [...]}
- If you already have a TraceData, do not round-trip through from_dict
Example fix
// before
TraceData.from_dict(open('trace.json').read())
// after
import json
TraceData.from_dict(json.loads(open('trace.json').read())) Defensive patterns
Strategy: validation
Validate before calling
import json
if isinstance(d, str):
d = json.loads(d)
if not isinstance(d, dict):
raise ValueError('trace payload must be a JSON object/dict') Type guard
def is_trace_dict(d) -> bool:
return isinstance(d, dict) and isinstance(d.get('spans', []), list) Try / catch
try:
trace = TraceData.from_dict(d)
except TypeError:
import json
trace = TraceData.from_dict(json.loads(d)) Prevention
- Always json.loads before from_dict
- Validate trace exports have a top-level object with 'spans'
- Never pass TraceData objects directly; use to_dict() output
When it happens
Trigger: Calling `TraceData.from_dict(json_string)` (passing a str), `TraceData.from_dict(list_of_spans)`, or `TraceData.from_dict(None)`; passing output of json.loads on a non-object JSON payload.
Common situations: Loading a trace from a JSON file that is a top-level array; passing the result of json.dumps (a string) instead of json.loads; passing a TraceData object instead of its to_dict() output.
Related errors
- INVALID_PARAMETER_VALUE
- status is required in trace info dictionary.
- The `requestPreview` parameter must be a string.
- The `responsePreview` parameter must be a string.
- Unsupported data type.
AI-assisted analysis of mlflow/mlflow@6a27f2decc (2026-08-29).
Data as JSON: /api/errors/b4e14b77b69d1df1.
Report an issue: GitHub.