OpenBB-finance/OpenBB · error · OpenBBError

Unexpected response format, expected a dictionary, got {resp

Error message

Unexpected response format, expected a dictionary, got {response.__class__.__name__}

What it means

OpenBBError raised in the historical market cap fetcher when amake_request with a response_callback returned something that is not a dict (e.g. a list, str, or None). The callback is expected to yield the parsed JSON object, so this means Intrinio's historical_data endpoint returned an unexpected top-level shape - typically a list payload or an error body not shaped like a dict.

Source

Thrown at openbb_platform/providers/intrinio/openbb_intrinio/models/historical_market_cap.py:111

        async def get_one(symbol):
            """Get data for one symbol."""
            url_params = (
                f"{symbol}/marketcap?{frequency}start_date={start_date}"
                f"&end_date={end_date}&page_size=10000"
                f"&api_key={api_key}"
            )
            url = f"{base_url}{url_params}"
            try:
                response = await amake_request(url, response_callback=response_callback)
            except OpenBBError as e:
                if "Cannot look up this item/identifier combination" in str(e):
                    msg = f"Symbol not found: {symbol}"
                    messages.append(msg)
                    return
                raise e from e

            if not isinstance(response, dict):
                raise OpenBBError(
                    f"Unexpected response format, expected a dictionary, got {response.__class__.__name__}"
                )

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

            if response.get("historical_data"):
                data = response.get("historical_data", {})
                result = [
                    {"symbol": symbol, **item} for item in data if item.get("value")
                ]
                results.extend(result)

            return

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

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. curl the URL 'https://api-v2.intrinio.com/historical_data/$SYMBOL/market_cap?api_key=KEY' to inspect the actual top-level JSON type.
  2. If a proxy/gateway interferes, bypass it or fix headers.
  3. Retry with the unescaped plain ticker (no $ prefix) - the fetcher builds the URL itself.
  4. Report to OpenBB with the symbol if Intrinio legitimately returns a list shape.
Defensive patterns

Strategy: type-guard

Validate before calling

# probe the endpoint shape for one symbol before batch use
import urllib.request, json
with urllib.request.urlopen(f'https://api-v2.intrinio.com/historical_data/$DJI/historical_data/level?api_key={key}') as r:
    payload = json.load(r)
assert isinstance(payload, dict), f'unexpected shape: {type(payload)}'

Type guard

def is_dict_payload(x) -> bool:
    return isinstance(x, dict)

Try / catch

from openbb_core.provider.exceptions import OpenBBError
try:
    res = obb.equity.fundamental.market_cap(symbol=sym, provider='intrinio')
except OpenBBError as e:
    if 'expected a dictionary' in str(e):
        log.error('intrinio returned non-dict payload for %s (proxy or API change?)', sym)
    raise

Prevention

When it happens

Trigger: equity/fundamental/market_cap(symbol=X, provider='intrinio') where the underlying $ symbol historical_data/value response is a JSON array or HTML/plain-text error (proxy page, gateway error), making response a non-dict; also possible if response_callback returns the results list instead of parsed JSON.

Common situations: Corporate actions causing the API to return an array of entries instead of the usual object; intermediary proxies returning HTML 502 pages; Intrinio A/B schema changes; symbols with special characters producing redirect bodies.

Related errors


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