OpenBB-finance/OpenBB · warning · EmptyDataError

{str(','.join(messages)).replace(',', ' ') if messages else

Error message

{str(','.join(messages)).replace(',', ' ') if messages else 'No data found'}

What it means

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.

Source

Thrown at openbb_platform/providers/fmp/openbb_fmp/utils/helpers.py:241

            data = response

        elif isinstance(response, dict) and response.get("historical"):
            data = response.get("historical", [])

        if not data:
            message = f"No data found for {symbol}."
            warn(message)
            messages.append(message)

        elif data:
            for d in data:
                d["symbol"] = symbol
                results.append(d)

    await asyncio.gather(*[get_one(symbol) for symbol in symbols])

    if not results:
        raise EmptyDataError(
            f"{str(','.join(messages)).replace(',', ' ') if messages else 'No data found'}"
        )

    return results


@lru_cache(maxsize=1)
def get_available_transcript_symbols(api_key) -> list:
    """Return the available symbols for earnings call transcripts."""
    # pylint: disable=import-outside-toplevel
    from openbb_core.provider.utils.helpers import make_request

    url = f"https://financialmodelingprep.com/stable/earnings-transcript-list?apikey={api_key}"

    data = make_request(url)

    data.raise_for_status()

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. For transcripts, call get_available_transcript_symbols(api_key) first and intersect your list with it
  2. Validate tickers against FMP's symbol list before bulk requests
  3. Split the batch and log per-symbol failures so partial data still flows - only the all-empty case raises
  4. Verify each failing symbol individually to distinguish invalid tickers from tier restrictions

Example fix

# before
res = await fetcher.fetch_data(query, credentials)  # all symbols empty -> raise

# after - pre-filter to symbols known to have coverage
available = set(get_available_transcript_symbols(api_key))
query.symbols = ','.join(s for s in query.symbols.split(',') if s in available)
res = await fetcher.fetch_data(query, credentials)
Defensive patterns

Strategy: validation

Validate before calling

from openbb_fmp.utils.helpers import get_available_transcript_symbols
available = set(get_available_transcript_symbols(api_key))
symbols = [s for s in symbols if s in available]
assert symbols, 'no requested symbols have transcript coverage'

Type guard

def all_symbols_covered(symbols: list[str], available: set[str]) -> bool:
    return all(s in available for s in symbols)

Try / catch

from openbb_core.provider.utils.errors import EmptyDataError
try:
    results = await fetcher.fetch_data(query, credentials)
except EmptyDataError as e:
    failed = [m for m in str(e).split() if 'No data found for' in m]
    log.warning('no data for: %s', failed)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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