OpenBB-finance/OpenBB · warning · OpenBBError

No holdings were found for {query.symbol}, and the response

Error message

No holdings were found for {query.symbol}, and the response from Intrinio was empty.

What it means

Raised in IntrinioEtfHoldingsFetcher.transform_data when data is falsy (empty list) — i.e. the holdings endpoint returned successfully but with an empty holdings array for the symbol. Note the guard: 'if not data or isinstance(data, dict) and data.get("error")' then an inner check that only the empty-list case produces this friendly message.

Source

Thrown at openbb_platform/providers/intrinio/openbb_intrinio/models/etf_holdings.py:196

                    next_page = results["next_page"]  # type: ignore
                    next_url = f"{URL}&next_page={next_page}"
                    results = await amake_request(next_url, session=session, **kwargs)
                    if "holdings" in results and len(results.get("holdings")) > 0:  # type: ignore
                        data.extend(results.get("holdings"))  # type: ignore
            return data

        return await amake_request(URL, response_callback=response_callback, **kwargs)  # type: ignore

    @staticmethod
    def transform_data(
        query: IntrinioEtfHoldingsQueryParams,
        data: list[dict],
        **kwargs: Any,
    ) -> list[IntrinioEtfHoldingsData]:
        """Transform data."""
        if not data or isinstance(data, dict) and data.get("error"):
            if isinstance(data, list) and data == []:
                raise OpenBBError(
                    str(
                        f"No holdings were found for {query.symbol}, and the response from Intrinio was empty."
                    )
                )
            raise OpenBBError(str(f"{data.get('message')} {query.symbol}: {data['error']}"))  # type: ignore

        results: list[IntrinioEtfHoldingsData] = []
        for d in sorted(data, key=lambda x: x["weighting"], reverse=True):
            # This field is deprecated and is dupilcated in the response.
            _ = d.pop("composite_figi", None)
            if d.get("coupon"):
                d["coupon"] = d["coupon"] / 100
            results.append(IntrinioEtfHoldingsData.model_validate(d))

        return results

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Confirm the symbol is actually an ETF (e.g. SPY, QQQ) — use obb.etf.search(provider='intrinio', query='...') to find valid ETF tickers
  2. Try the ticker without exchange suffixes/punctuation, or with Intrinio's standard formatting
  3. Fall back to another provider that sources holdings differently (e.g. 'fmp') if the ETF is valid but missing

Example fix

# before
holdings = obb.etf.holdings(provider="intrinio", symbol="SPX").to_df()

# after
holdings = obb.etf.holdings(provider="intrinio", symbol="SPY").to_df()
Defensive patterns

Strategy: try-catch

Validate before calling

KNOWN_ETFS = {"SPY", "QQQ", "IWM", "VTI", "EFA"}  # seed from obb.etf.search once

def is_likely_etf(symbol: str) -> bool:
    return symbol.upper() in KNOWN_ETFS

Type guard

from openbb_core.provider.abstract.error import OpenBBError

def is_empty_holdings(err: BaseException) -> bool:
    return isinstance(err, OpenBBError) and "response from Intrinio was empty" in str(err)

Try / catch

from openbb_core.provider.abstract.error import OpenBBError
from openbb_core.provider.utils.errors import EmptyDataError

try:
    holdings = await obb.etf.holdings(provider="intrinio", symbol=sym)
except OpenBBError as e:
    if "response from Intrinio was empty" in str(e):
        holdings = await obb.etf.holdings(provider="fmp", symbol=sym)  # fallback provider
    else:
        raise

Prevention

When it happens

Trigger: Requesting ETF holdings for a valid ticker that is not an ETF (a stock or index), an ETF Intrinio has no holdings data for, or a share-class/FIGI formatting issue in the URL. The endpoint answers 200 with [] rather than an error payload.

Common situations: Passing indices like 'SPX' or 'DJI' (not tradable ETFs); using a ticker suffix Intrinio doesn't expect; obscure/young ETFs not yet in Intrinio's holdings database; assuming every ticker works because a previous ETF did.

Related errors


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