OpenBB-finance/OpenBB · error · OpenBBError

Invalid data format. Expected a list of ImfPortInfoData.

Error message

Invalid data format. Expected a list of ImfPortInfoData.

What it means

Type guard in the port-info map view: data must be a list of ImfPortInfoData instances. Due to operator precedence the check is (data is not None and not isinstance(data, list)) or not all(isinstance(item, ImfPortInfoData)); any non-list input, any item of the wrong type, or mixed content triggers it. None input is not rejected here and fails later at len().

Source

Thrown at openbb_platform/providers/imf/openbb_imf/views/port_info.py:27

    from numpy import nan
    from openbb_core.app.model.abstract.error import OpenBBError
    from pandas import DataFrame

    try:
        import plotly.express as px
        from openbb_charting.core.openbb_figure import OpenBBFigure
    except Exception as e:
        raise OpenBBError(
            "Could not import Charting modules. Install with `pip install openbb-charting`."
            + f" -> {e}"
        ) from e

    if (
        data is not None
        and not isinstance(data, list)
        or not all(isinstance(item, ImfPortInfoData) for item in data)
    ):
        raise OpenBBError("Invalid data format. Expected a list of ImfPortInfoData.")
    if len(data) == 0:
        raise OpenBBError("No data to plot.")

    df = DataFrame([item.model_dump() for item in data]).query("vessel_count_total > 0")

    min_size, max_size = 4, 10

    if "country" in df.columns and df["country"].nunique() == 1:
        share_import = df["share_country_maritime_import"].fillna(0)
        share_export = df["share_country_maritime_export"].fillna(0)
        df["import_export_share"] = share_import + share_export
        share_values = df["import_export_share"]

        if share_values.nunique() > 1:
            df["marker_size"] = (
                (share_values - share_values.min())
                / (share_values.max() - share_values.min() + 1e-9)
            ) * (max_size - min_size) + min_size

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Pass the endpoint's model-validated results list directly.
  2. Re-validate dicts first: [ImfPortInfoData.model_validate(d) for d in rows].
  3. Check for None before calling (guard does not cover it).
  4. Keep homogeneous lists - one model type per call.

Example fix

# before
plot_port_info_map(port_rows_as_dicts)
# after
from openbb_imf.models.port_info import ImfPortInfoData
plot_port_info_map([ImfPortInfoData.model_validate(d) for d in port_rows_as_dicts])
Defensive patterns

Strategy: type-guard

Validate before calling

from openbb_imf.models.port_info import ImfPortInfoData

def is_port_info_list(data) -> bool:
    return isinstance(data, list) and len(data) > 0 and all(
        isinstance(i, ImfPortInfoData) for i in data
    )

Type guard

from openbb_imf.models.port_info import ImfPortInfoData

def is_port_info_list(data: object) -> bool:
    return isinstance(data, list) and len(data) > 0 and all(
        isinstance(i, ImfPortInfoData) for i in data
    )

Try / catch

from openbb_core.app.model.abstract.error import OpenBBError
try:
    plot_port_info_map(data)
except OpenBBError as e:
    if 'Invalid data format' in str(e) and isinstance(data, list):
        plot_port_info_map([ImfPortInfoData.model_validate(d) for d in data])
    else:
        raise

Prevention

When it happens

Trigger: Passing a DataFrame, list of dicts, generator, or a list mixing ImfPortInfoData with raw rows/different provider models into plot_port_info_map; forwarding deserialized (dict) results from an API response instead of model instances.

Common situations: Callers converting fetcher output to dicts/JSON for transport, then calling the chart view without re-validating; combining port data with other maritime results; mock objects in tests failing isinstance checks.

Related errors


AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14). Data as JSON: /api/errors/0e555f6b278cfc7d. Report an issue: GitHub.