OpenBB-finance/OpenBB · error · OpenBBError

Error: option_type must be either 'call' or 'put'

Error message

Error: option_type must be either 'call' or 'put'

What it means

Raised at the top of OptionsChainsData._get_nearest_strike (options_chains_properties.py), the helper behind straddle/strangle strike selection. It hard-validates option_type against the literal list ['call', 'put'] before touching the chains data; any other string (or non-string) raises immediately.

Source

Thrown at openbb_platform/core/openbb_core/provider/utils/options_chains_properties.py:612

        days: int
            The target number of days until expiry.  Default is 30 days.
        strike: float
            The target strike price.  Default is the last price of the underlying stock.
        price_col: str
            The price column to use for the calculation.
        force_otm: bool
            If True, the nearest OTM strike is returned.  Default is True.

        Returns
        -------
        float
            The closest strike price to the target price and number of days until expiry.
        """
        # pylint: disable=import-outside-toplevel
        from pandas import Series

        if option_type not in ["call", "put"]:
            raise OpenBBError("Error: option_type must be either 'call' or 'put'")

        chains = self.dataframe
        days = -1 if days == 0 else days

        if days is None:
            days = 30

        dte_estimate = self._get_nearest_expiration(days)
        df = (
            chains[chains.expiration.astype(str) == dte_estimate]
            .query("`option_type` == @option_type")
            .copy()
        )
        if strike is None:
            strike = df.underlying_price.iloc[0]

        if price_col is not None:
            df = df[df[price_col].notnull()]  # type: ignore

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Normalize to lowercase 'call' or 'put' before the call: option_type=option_type.lower()
  2. Map common shorthands at your boundary: {'C': 'call', 'P': 'put'}
  3. Validate with a small whitelist guard so bad values never reach the helper

Example fix

# before
price, dte = res.straddle(option_type="C")  # OpenBBError: option_type must be 'call' or 'put'

# after
price, dte = res.straddle(option_type="call")
Defensive patterns

Strategy: type-guard

Validate before calling

OPTION_TYPES = {"call", "put"}
option_type = str(option_type).lower()
if option_type not in OPTION_TYPES:
    raise ValueError(f"option_type must be 'call' or 'put', got {option_type!r}")

Type guard

from typing import Literal

OptionType = Literal["call", "put"]

def is_valid_option_type(v) -> bool:
    return isinstance(v, str) and v.lower() in {"call", "put"}

Try / catch

from openbb_core.app.model.abstract.error import OpenBBError

try:
    out = res.straddle(option_type=option_type, dte=30)
except OpenBBError as e:
    if "option_type must be either" in str(e):
        out = res.straddle(option_type="call", dte=30)
    else:
        raise

Prevention

When it happens

Trigger: Calling result.straddle(...)/result.strangle(...) with option_type='C'/'P'/'CALL'/'Call'/None or a symbol-style value. Only exact lowercase 'call' and 'put' pass.

Common situations: Convention clash with other APIs (OCC symbology uses C/P); uppercase data from user forms or upstream CSVs passed through unnormalized.

Related errors


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