{"record":{"id":"ddf381acc32ceb66","repo":"OpenBB-finance/OpenBB","slug":"str-join-messages-replace-if-mess","errorCode":null,"errorMessage":"{str(','.join(messages)).replace(',', ' ') if messages else 'No data found'}","messagePattern":"\\{str\\(','\\.join\\(messages\\)\\)\\.replace\\(',', ' '\\) if messages else 'No data found'\\}","errorType":"exception","errorClass":"EmptyDataError","httpStatus":null,"severity":"warning","filePath":"openbb_platform/providers/fmp/openbb_fmp/utils/helpers.py","lineNumber":241,"sourceCode":"            data = response\n\n        elif isinstance(response, dict) and response.get(\"historical\"):\n            data = response.get(\"historical\", [])\n\n        if not data:\n            message = f\"No data found for {symbol}.\"\n            warn(message)\n            messages.append(message)\n\n        elif data:\n            for d in data:\n                d[\"symbol\"] = symbol\n                results.append(d)\n\n    await asyncio.gather(*[get_one(symbol) for symbol in symbols])\n\n    if not results:\n        raise EmptyDataError(\n            f\"{str(','.join(messages)).replace(',', ' ') if messages else 'No data found'}\"\n        )\n\n    return results\n\n\n@lru_cache(maxsize=1)\ndef get_available_transcript_symbols(api_key) -> list:\n    \"\"\"Return the available symbols for earnings call transcripts.\"\"\"\n    # pylint: disable=import-outside-toplevel\n    from openbb_core.provider.utils.helpers import make_request\n\n    url = f\"https://financialmodelingprep.com/stable/earnings-transcript-list?apikey={api_key}\"\n\n    data = make_request(url)\n\n    data.raise_for_status()\n","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/fmp/openbb_fmp/utils/helpers.py#L223-L259","documentation":"Raised by FMP's multi-symbol gather helper (used by fetch_data_many over many symbols) when every requested symbol warned 'No data found for {symbol}' and the aggregated results list is empty. The message joins all per-symbol warnings into one EmptyDataError so the caller sees exactly which symbols failed.","triggerScenarios":"Passing a batch of symbols to an FMP endpoint where none returned data - e.g. earnings-call transcripts restricted to a limited symbol universe, or a list of invalid tickers.","commonSituations":"Bulk-fetching transcripts or batch data with free-tier keys whose symbol coverage is a small subset; feeding unvalidated tickers from a scraped list; requesting symbols whose data FMP has not indexed for that dataset.","solutions":["For transcripts, call get_available_transcript_symbols(api_key) first and intersect your list with it","Validate tickers against FMP's symbol list before bulk requests","Split the batch and log per-symbol failures so partial data still flows - only the all-empty case raises","Verify each failing symbol individually to distinguish invalid tickers from tier restrictions"],"exampleFix":"# before\nres = await fetcher.fetch_data(query, credentials)  # all symbols empty -> raise\n\n# after - pre-filter to symbols known to have coverage\navailable = set(get_available_transcript_symbols(api_key))\nquery.symbols = ','.join(s for s in query.symbols.split(',') if s in available)\nres = await fetcher.fetch_data(query, credentials)","handlingStrategy":"validation","validationCode":"from openbb_fmp.utils.helpers import get_available_transcript_symbols\navailable = set(get_available_transcript_symbols(api_key))\nsymbols = [s for s in symbols if s in available]\nassert symbols, 'no requested symbols have transcript coverage'","typeGuard":"def all_symbols_covered(symbols: list[str], available: set[str]) -> bool:\n    return all(s in available for s in symbols)","tryCatchPattern":"from openbb_core.provider.utils.errors import EmptyDataError\ntry:\n    results = await fetcher.fetch_data(query, credentials)\nexcept EmptyDataError as e:\n    failed = [m for m in str(e).split() if 'No data found for' in m]\n    log.warning('no data for: %s', failed)","preventionTips":["Intersect symbol batches with get_available_transcript_symbols before fetching","Chunk large symbol lists so one all-empty chunk does not abort the run","Parse the joined message to identify exactly which symbols failed"],"tags":["fmp","batch","transcripts","empty-data","multi-symbol"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}