{"record":{"id":"0b61630cda4d3305","repo":"OpenBB-finance/OpenBB","slug":"error-option-type-must-be-either-call-or-put","errorCode":null,"errorMessage":"Error: option_type must be either 'call' or 'put'","messagePattern":"Error: option_type must be either 'call' or 'put'","errorType":"exception","errorClass":"OpenBBError","httpStatus":null,"severity":"error","filePath":"openbb_platform/core/openbb_core/provider/utils/options_chains_properties.py","lineNumber":612,"sourceCode":"        days: int\n            The target number of days until expiry.  Default is 30 days.\n        strike: float\n            The target strike price.  Default is the last price of the underlying stock.\n        price_col: str\n            The price column to use for the calculation.\n        force_otm: bool\n            If True, the nearest OTM strike is returned.  Default is True.\n\n        Returns\n        -------\n        float\n            The closest strike price to the target price and number of days until expiry.\n        \"\"\"\n        # pylint: disable=import-outside-toplevel\n        from pandas import Series\n\n        if option_type not in [\"call\", \"put\"]:\n            raise OpenBBError(\"Error: option_type must be either 'call' or 'put'\")\n\n        chains = self.dataframe\n        days = -1 if days == 0 else days\n\n        if days is None:\n            days = 30\n\n        dte_estimate = self._get_nearest_expiration(days)\n        df = (\n            chains[chains.expiration.astype(str) == dte_estimate]\n            .query(\"`option_type` == @option_type\")\n            .copy()\n        )\n        if strike is None:\n            strike = df.underlying_price.iloc[0]\n\n        if price_col is not None:\n            df = df[df[price_col].notnull()]  # type: ignore","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/core/openbb_core/provider/utils/options_chains_properties.py#L594-L630","documentation":"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.","triggerScenarios":"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.","commonSituations":"Convention clash with other APIs (OCC symbology uses C/P); uppercase data from user forms or upstream CSVs passed through unnormalized.","solutions":["Normalize to lowercase 'call' or 'put' before the call: option_type=option_type.lower()","Map common shorthands at your boundary: {'C': 'call', 'P': 'put'}","Validate with a small whitelist guard so bad values never reach the helper"],"exampleFix":"# before\nprice, dte = res.straddle(option_type=\"C\")  # OpenBBError: option_type must be 'call' or 'put'\n\n# after\nprice, dte = res.straddle(option_type=\"call\")","handlingStrategy":"type-guard","validationCode":"OPTION_TYPES = {\"call\", \"put\"}\noption_type = str(option_type).lower()\nif option_type not in OPTION_TYPES:\n    raise ValueError(f\"option_type must be 'call' or 'put', got {option_type!r}\")","typeGuard":"from typing import Literal\n\nOptionType = Literal[\"call\", \"put\"]\n\ndef is_valid_option_type(v) -> bool:\n    return isinstance(v, str) and v.lower() in {\"call\", \"put\"}","tryCatchPattern":"from openbb_core.app.model.abstract.error import OpenBBError\n\ntry:\n    out = res.straddle(option_type=option_type, dte=30)\nexcept OpenBBError as e:\n    if \"option_type must be either\" in str(e):\n        out = res.straddle(option_type=\"call\", dte=30)\n    else:\n        raise","preventionTips":["Type option_type as Literal['call','put'] throughout your codebase","Normalize C/P and CALL/PUT shorthands from external data at ingest time","Lowercase user input before it reaches strategy methods"],"tags":["options","validation","option-type","derivatives"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}