OpenBB-finance/OpenBB · error · OpenBBError

Expiration field not found in the data.

Error message

Expiration field not found in the data.

What it means

Raised by the derivatives futures curve charting view when the assembled DataFrame has no 'expiration' column. The curve plot maps each expiration to a point on the x-axis, so the field is mandatory regardless of provider. It fires after the empty-check, on any non-empty frame missing that column.

Source

Thrown at openbb_platform/extensions/derivatives/openbb_derivatives/derivatives_views.py:102

        if data:
            if isinstance(data, DataFrame) and not data.empty:  # noqa: SIM108
                df = data
            elif isinstance(data, (list, Data)):
                df = DataFrame([d.model_dump(exclude_none=True, exclude_unset=True) for d in data])  # type: ignore
            else:
                pass
        else:
            df = DataFrame(
                [d.model_dump(exclude_none=True, exclude_unset=True) for d in kwargs["obbject_item"]]  # type: ignore
                if isinstance(kwargs.get("obbject_item"), list)
                else kwargs["obbject_item"].model_dump(exclude_none=True, exclude_unset=True)  # type: ignore
            )

        if df.empty:
            raise OpenBBError("Error: No data to plot.")

        if "expiration" not in df.columns:
            raise OpenBBError("Expiration field not found in the data.")

        if "price" not in df.columns:
            raise ValueError("Price field not found in the data.")

        provider = kwargs.get("provider", "")

        if provider != "deribit":
            df["expiration"] = df["expiration"].apply(to_datetime).dt.strftime("%b-%Y")

        if (
            provider == "cboe"
            and "date" in df.columns
            and len(df["date"].unique()) > 1
            and "symbol" in df.columns
        ):
            df["expiration"] = df.symbol

        # Use a complete list of expirations to categorize the x-axis across all dates.

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Feed curve data, not historical data: use obb.derivatives.futures.curve results.
  2. If supplying custom data, ensure each record has an 'expiration' field and rename 'expiry'/'maturity' to 'expiration'.
  3. Avoid dumping with exclude_unset when expiration may be unset; materialize the column first.
  4. Verify: 'expiration' in df.columns before calling to_chart/show.

Example fix

# before
df = my_expiry_frame.rename(columns={'maturity': 'expiration'}) if ... else my_expiry_frame  # missing column

# after
df = my_expiry_frame.rename(columns={'maturity': 'expiration'})
assert 'expiration' in df.columns and 'price' in df.columns
fig, _ = obb.derivatives.futures.curve charting with data=df
Defensive patterns

Strategy: validation

Validate before calling

df = <your frame>
if 'expiration' not in df.columns:
    df = df.rename(columns={'expiry': 'expiration', 'maturity': 'expiration'})
assert 'expiration' in df.columns, 'curve chart requires expiration'

Type guard

def curve_ready(df) -> bool:
    return not df.empty and {'expiration', 'price'} <= set(df.columns)

Prevention

When it happens

Trigger: Calling the futures curve chart with data= (a custom DataFrame or list of Data models) whose fields don't include 'expiration' - e.g. feeding a futures historical (price-by-date) payload instead of a curve payload, or a model with expiration excluded by exclude_none/exclude_unset because all values were None.

Common situations: Passing the wrong endpoint's results to the curve chart; Data models serialized with exclude_none dropping a None expiration; column renamed in user-side preprocessing (e.g. 'expiry').

Related errors


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