{"record":{"id":"c583111d015f0373","repo":"OpenBB-finance/OpenBB","slug":"error-stat-must-be-one-of-open-interest-volu","errorCode":null,"errorMessage":"Error: stat must be one of ['open_interest', 'volume', 'dex', 'gex']","messagePattern":"Error: stat must be one of \\['open_interest', 'volume', 'dex', 'gex'\\]","errorType":"exception","errorClass":"OpenBBError","httpStatus":null,"severity":"error","filePath":"openbb_platform/core/openbb_core/provider/utils/options_chains_properties.py","lineNumber":332,"sourceCode":"            This is ignored if stat is not None.\n        stat: Optional[Literal[\"open_interest\", \"volume\", \"dex\", \"gex\"]]\n            The statistical metric to filter by.\n            Other fields are ignored if this is not None.\n        by: Literal[\"expiration\", \"strike\"]\n            Filter the `stat` by expiration or strike, default is \"expiration\".\n            If a date is supplied, \"strike\" is always returned.\n            This is ignored if `stat` is None.\n        \"\"\"\n        # pylint: disable=import-outside-toplevel\n        from numpy import nan\n        from pandas import DataFrame, concat\n\n        stats = [\"open_interest\", \"volume\", \"dex\", \"gex\"]\n        _stat = stat.upper() if stat in [\"dex\", \"gex\"] else stat\n        by = \"strike\" if date is not None else by\n        if stat is not None:\n            if stat not in stats:\n                raise OpenBBError(f\"Error: stat must be one of {stats}\")\n            if stat in [\"volume\", \"open_interest\"]:\n                return DataFrame(self._get_stat(stat, moneyness=moneyness, date=date)[by]).replace({nan: None})  # type: ignore\n            if (\n                _stat not in self.dataframe.columns\n                and self.has_greeks\n                and \"underlying_price\" not in self.dataframe.columns\n            ):\n                raise OpenBBError(\n                    f\"Error: '{stat}' could not be generated because\"\n                    + \" the underlying price was not returned by the provider.\"\n                    + \" Set manually with 'underlying_price' property.\"\n                )\n            df = DataFrame(self._get_stat(_stat, moneyness=moneyness, date=date)[by])  # type: ignore\n            return df.replace({nan: None})\n\n        df = self.dataframe\n\n        if moneyness is not None:","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/core/openbb_core/provider/utils/options_chains_properties.py#L314-L350","documentation":"Raised at the top of OptionsChainsData.filter_data(stat=...) (options_chains_properties.py). The stat parameter only accepts the fixed set ['open_interest', 'volume', 'dex', 'gex'] (case-sensitive); anything else is rejected before any filtering happens. 'dex'/'gex' are uppercased internally for column lookup but must be passed lowercase.","triggerScenarios":"Calling result.filter_data(stat='DEX') or stat='Delta', 'gamma', 'iv', 'oi' — any variant spelling or case mismatch triggers it, because only the exact lowercase four strings are allowed.","commonSituations":"Passing column-name-style values from the DataFrame ('DEX' computed column) back into filter_data; assuming case-insensitivity like other OpenBB lookups (country/exchange) provide.","solutions":["Use exactly one of: 'open_interest', 'volume', 'dex', 'gex' (lowercase)","Derive the value from the hardcoded list or an enum rather than free text","For other columns (e.g. 'delta', 'iv'), use the column= parameter path instead of stat="],"exampleFix":"# before\ndf = res.filter_data(stat=\"DEX\")  # OpenBBError: stat must be one of [...]\n\n# after\ndf = res.filter_data(stat=\"dex\")\n# or, for an arbitrary column:\ndf = res.filter_data(column=\"delta\", value_min=-0.5, value_max=0.5)","handlingStrategy":"type-guard","validationCode":"VALID_STATS = {\"open_interest\", \"volume\", \"dex\", \"gex\"}\nstat = stat.lower() if isinstance(stat, str) else stat\nif stat is not None and stat not in VALID_STATS:\n    raise ValueError(f\"stat must be one of {sorted(VALID_STATS)}\")","typeGuard":"from typing import Literal, Optional\n\nStat = Optional[Literal[\"open_interest\", \"volume\", \"dex\", \"gex\"]]\n\ndef is_valid_stat(s) -> bool:\n    return s is None or s in {\"open_interest\", \"volume\", \"dex\", \"gex\"}","tryCatchPattern":"from openbb_core.app.model.abstract.error import OpenBBError\n\ntry:\n    df = res.filter_data(stat=stat)\nexcept OpenBBError as e:\n    if \"stat must be one of\" in str(e):\n        df = res.filter_data(stat=\"volume\")  # sensible default\n    else:\n        raise","preventionTips":["Type stat as a Literal union so mypy rejects bad values at write time","Lowercase user input and whitelist-check before calling filter_data","Use column= (not stat=) for arbitrary columns like 'delta' or 'iv'"],"tags":["options","filter","enum","derivatives"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}