OpenBB-finance/OpenBB · error · ValueError
Failed to convert chart to JSON
Error message
Failed to convert chart to JSON
What it means
Thrown by the OmniWidgetResponseModel Pydantic model_validator when the content is detected as a plotly Figure (duck-typed by class name) but calling Figure.to_json() raises. The widget response pipeline serializes charts to JSON for the frontend; any exception during plotly serialization is wrapped in this ValueError.
Source
Thrown at openbb_platform/extensions/platform_api/openbb_platform_api/response_models.py:239
)
# If parameter was supplied, assume the data is formatted correctly.
if content and parse_as:
data_format = {
"data_type": "object",
"parse_as": parse_as,
}
values.data_format = data_format
del values.parse_as
return values
if content.__class__.__name__ == "Figure":
values.parse_as = "chart"
try:
content = content.to_json()
except Exception as e:
raise ValueError("Failed to convert chart to JSON") from e
values.content = content
elif isinstance(content, dict) and "layout" in content and "data" in content:
values.parse_as = "chart"
elif isinstance(content, list) and all(
isinstance(item, dict) for item in content
):
values.parse_as = "table"
elif isinstance(content, pd.DataFrame):
values.parse_as = "table"
try:
content = json.loads(content.to_json(orient="records"))
except Exception as e:
raise ValueError("Failed to convert DataFrame to JSON") from e
values.content = content
elif isinstance(content, dict) and all(
isinstance(v, list) for v in content.values()
):
values.parse_as = "table"View on GitHub (pinned to 3e071fcc2c)
Solutions
- Verify the object is a plotly.graph_objs.Figure (or plotly FigureWidget), not a matplotlib.figure.Figure.
- Test fig.to_json() standalone in a REPL to surface the underlying exception chained via __cause__.
- Pre-convert the Figure yourself with json.loads(fig.to_json()) and pass the resulting dict, or pass parse_as='chart' with the already-serialized dict {'data':..., 'layout':...}.
- Sanitize the Figure before passing it: cast Timestamp indices to strings and replace non-serializable values.
Example fix
# before resp = OmniWidgetResponseModel(content=matplotlib_fig) # wrong Figure class # after import plotly.graph_objects as go fig = go.Figure(...) # plotly Figure resp = OmniWidgetResponseModel(content=fig)
Defensive patterns
Strategy: validation
Validate before calling
from plotly.graph_objs import Figure
if not isinstance(content, Figure):
raise TypeError("content must be a plotly Figure, dict, or list of records")
content = json.loads(content.to_json()) # fail early, before the model validator Type guard
def is_plotly_figure(obj) -> bool:
return obj.__class__.__name__ == "Figure" and hasattr(obj, "to_json") Try / catch
try:
resp = OmniWidgetResponseModel(content=fig)
except ValueError as e:
if "chart to JSON" in str(e) and e.__cause__:
logger.error("plotly serialization failed: %s", e.__cause__)
raise Prevention
- Pass plotly figures only, never matplotlib
- Pre-serialize with fig.to_json() in tests to catch encoding problems
- Inspect __cause__ on the wrapped ValueError for the root error
When it happens
Trigger: Constructing OmniWidgetResponseModel(content=<plotly Figure object>) where the Figure contains objects plotly cannot serialize (e.g. custom dtypes, NaN-heavy data, non-JSON-serializable custom trace attributes, or a numpy array inside hovertemplate data), or where 'Figure' is a different class that also has a failing to_json().
Common situations: Passing a matplotlib figure (also named Figure) instead of a plotly one; a Figure built from a DataFrame with Timestamp/TimestampTZ indices or Decimal values that plotly's JSON encoder rejects; plotly version changes that alter to_json behavior.
Related errors
- Failed to convert DataFrame to JSON
- Failed to convert dictionary of lists to list of records
- At least one extension type must be selected.
- Incorrect email or password
- Charting is not installed. Please install `openbb-charting`.
AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14).
Data as JSON: /api/errors/6c92b8a8f6cf66dc.
Report an issue: GitHub.