OpenBB-finance/OpenBB · error · OpenBBError

Error: strike must be provided if underlying_price is not av

Error message

Error: strike must be provided if underlying_price is not available

What it means

Raised in OptionsChainsData.strangle (options_chains_properties.py:712). When no strike was supplied, the strategy normally defaults the target strike to the underlying price; if the underlying price is unavailable (no column) AND strike is None, there is no anchor left, so it raises this sibling of error 58. If strike IS provided it sets force_otm=False and proceeds.

Source

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

        dte_estimate = self._get_nearest_expiration(days)

        chains = chains[chains.expiration.astype(str) == dte_estimate]

        if not hasattr(chains, "underlying_price") and underlying_price is None:
            raise OpenBBError(
                "Error: underlying_price must be provided if underlying_price is not available"
            )
        underlying_price = (
            underlying_price
            if underlying_price is not None
            else chains.underlying_price.iloc[0]
        )

        force_otm = True

        if strike is None and not hasattr(chains, "underlying_price"):
            raise OpenBBError(
                "Error: strike must be provided if underlying_price is not available"
            )

        if strike is not None:
            force_otm = False

        if strike is None:
            strike = underlying_price

        if strike is not None and strike < 0:
            short = True

        strike_price = abs(strike)  # type: ignore
        bid_ask = "bid" if short else "ask"
        call_price_col = self._identify_price_col(chains, "call", bid_ask)  # type: ignore
        put_price_col = self._identify_price_col(chains, "put", bid_ask)  # type: ignore
        call_strike_estimate = self._get_nearest_strike("call", days, strike_price, call_price_col, force_otm)  # type: ignore
        # If a strike price is supplied, the put strike is the same as the call strike.

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Pass an explicit strike: res.strangle(..., strike=585)
  2. Or supply underlying_price so the strike defaults to the spot
  3. Or set res.last_price before calling so underlying_price is available in the dataframe

Example fix

# before
out = res.strangle(dte=30)  # no spot column, no strike -> OpenBBError

# after
out = res.strangle(dte=30, strike=585)  # explicit strike anchor
Defensive patterns

Strategy: validation

Validate before calling

has_spot = "underlying_price" in res.to_df().columns or res.last_price is not None
if strike is None and not has_spot and underlying_price is None:
    raise ValueError("strangle needs a strike or an underlying price")
out = res.strangle(dte=30, strike=strike, underlying_price=underlying_price)

Type guard

def has_strike_anchor(res, strike=None, underlying_price=None) -> bool:
    return strike is not None or underlying_price is not None or "underlying_price" in res.to_df().columns or res.last_price is not None

Try / catch

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

try:
    out = res.strangle(dte=30)
except OpenBBError as e:
    if "strike must be provided" in str(e) or "underlying_price must be provided" in str(e):
        out = res.strangle(dte=30, strike=round_to_strike(get_spot(symbol)))
    else:
        raise

Prevention

When it happens

Trigger: Calling result.strangle(dte=30, underlying_price=None) without strike= on data lacking the underlying_price column. Providing strike= (or an underlying_price=, which satisfies the earlier check) avoids this branch.

Common situations: Same strangle setup as error 58: spot-free provider payloads where the caller also omitted an explicit strike; automation loops that only pass dte.

Related errors


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