{"record":{"id":"3a6b3769e596d738","repo":"OpenBB-finance/OpenBB","slug":"expected-dict-got-empty-list","errorCode":null,"errorMessage":"Expected dict, got empty list","messagePattern":"Expected dict, got empty list","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/fmp/openbb_fmp/utils/helpers.py","lineNumber":133,"sourceCode":"    \"\"\"\n    data = await get_data(url, **kwargs)\n\n    if sub_dict and isinstance(data, dict):\n        data = data.get(sub_dict, [])\n    if isinstance(data, dict):\n        raise ValueError(\"Expected list of dicts, got dict\")\n    if len(data) == 0:\n        raise EmptyDataError()\n\n    return data\n\n\nasync def get_data_one(url: str, **kwargs: Any) -> dict:\n    \"\"\"Get data from FMP endpoint and convert to schema.\"\"\"\n    data = await get_data(url, **kwargs)\n    if isinstance(data, list):\n        if len(data) == 0:\n            raise ValueError(\"Expected dict, got empty list\")\n\n        try:\n            data = {i: data[i] for i in range(len(data))} if len(data) > 1 else data[0]\n        except TypeError as e:\n            raise ValueError(\"Expected dict, got list of dicts\") from e\n\n    return data\n\n\ndef most_recent_quarter(base: date | None = None) -> date:\n    \"\"\"Get the most recent quarter date.\"\"\"\n    if base is None:\n        base = date.today()\n    base = min(base, date.today())  # This prevents dates from being in the future\n    exacts = [(3, 31), (6, 30), (9, 30), (12, 31)]\n    for exact in exacts:\n        if base.month == exact[0] and base.day == exact[1]:\n            return base","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/fmp/openbb_fmp/utils/helpers.py#L115-L151","documentation":"Raised by openbb_fmp get_data_one when the FMP response is a list with zero elements but the caller needs a single dict. The helper is used for endpoints expected to return one object (profile, quote, etc.), so an empty list means the symbol simply has no record.","triggerScenarios":"Calling a single-object FMP endpoint (e.g. /profile/) with a symbol FMP does not cover: invalid ticker, wrong exchange suffix, delisted company, or an asset class (crypto/forex) the endpoint does not serve.","commonSituations":"Typos in tickers (APPL vs AAPL), tickers with dots or suffixes FMP does not use (BRK.B vs BRK-B), recently delisted companies, or free-tier keys restricted from certain symbols.","solutions":["Validate the symbol with FMP's search endpoint (/api/v3/search?query=...) and use the returned symbol exactly","Check for delisting or exchange-specific formatting (FMP uses hyphens for share classes, e.g. BRK-B)","Confirm the endpoint covers that asset class","Handle the ValueError in caller code to skip unknown symbols in batch loops"],"exampleFix":"# before\nprofile = await get_data_one(f\"{base}profile?symbol={symbol}&apikey={key}\")\n\n# after\ntry:\n    profile = await get_data_one(f\"{base}profile?symbol={symbol}&apikey={key}\")\nexcept ValueError:\n    continue  # skip symbols FMP does not cover","handlingStrategy":"try-catch","validationCode":"import requests\nr = requests.get(f\"https://financialmodelingprep.com/stable/search-ticker?query={symbol}&apikey={key}\")\nmatches = r.json() if r.status_code == 200 else []\nassert matches, f'{symbol} unknown to FMP'","typeGuard":"def symbol_exists_on_fmp(symbol: str, search_results: list[dict]) -> bool:\n    return any(item.get(\"symbol\") == symbol for item in search_results)","tryCatchPattern":"try:\n    profile = await get_data_one(url)\nexcept ValueError as e:\n    if 'empty list' in str(e):\n        continue  # symbol not covered - skip in batch loops\n    raise","preventionTips":["Pre-validate tickers against FMP's search endpoint and cache the result","Normalize share-class separators to FMP's hyphen format (BRK-B, BF-B)","Wrap per-symbol calls in ValueError handlers in batch pipelines"],"tags":["fmp","empty-response","invalid-symbol","validation"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}