OpenBB-finance/OpenBB · error · OpenBBError

{data.get('message')} {query.symbol}: {data['error']}

Error message

{data.get('message')} {query.symbol}: {data['error']}

What it means

The companion branch of etf_holdings transform_data: the response is a dict containing an 'error' key (not a list), so the fetcher surfaces Intrinio's own message and error for the requested symbol. Format: '<message> <symbol>: <error>'.

Source

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

            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. Read the embedded Intrinio message/error pair — it names the exact upstream reason
  2. Validate the ticker is a known ETF via obb.etf.search(provider='intrinio') before requesting holdings
  3. Normalize the symbol (strip suffixes like ':US' where not expected) and retry
  4. Verify your Intrinio plan includes ETF holdings data
Defensive patterns

Strategy: try-catch

Type guard

from openbb_core.provider.abstract.error import OpenBBError

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

Try / catch

from openbb_core.provider.abstract.error import OpenBBError

try:
    holdings = await obb.etf.holdings(provider="intrinio", symbol=sym)
except OpenBBError as e:
    # message embeds Intrinio's <message> <symbol>: <error>
    log.warning("intrinio holdings failed for %s: %s", sym, e)
    raise

Prevention

When it happens

Trigger: The Intrinio ETF holdings endpoint returns an error object for the given symbol: unknown/invalid ticker, ticker that is not an ETF, or API/plan-level errors. Because the payload is a dict, the empty-list branch is skipped and this error-in-response branch fires.

Common situations: Typos or delisted tickers; passing common stocks where an ETF is expected; plan restrictions on the holdings endpoint; symbol formatting Intrinio rejects (e.g. dots or suffixed share classes).

Related errors


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