OpenBB-finance/OpenBB · error · ValueError

Exchange '{v.name}' ({v.mic}) is not supported by FMP. Valid

Error message

Exchange '{v.name}' ({v.mic}) is not supported by FMP. Valid options: {', '.join(sorted(valid_exchanges)[:20])}...

What it means

A Pydantic field_validator ValueError on FMPEquityScreenerQueryParams.exchange: the Exchange object's lowercase acronym is checked against the FMP-supported exchange set (Exchanges Literal). Passing an exchange FMP does not serve (by MIC) is rejected client-side with the first 20 valid acronyms in the message.

Source

Thrown at openbb_platform/providers/fmp/openbb_fmp/models/equity_screener.py:191

        valid_countries = list(Countries.__args__)
        if country_code not in valid_countries:
            raise ValueError(
                f"Country '{v.name}' ({v.alpha_2}) is not supported by FMP. "
                f"Valid options: {', '.join(sorted(valid_countries)[:20])}..."
            )
        return v

    @field_validator("exchange", mode="after")
    @classmethod
    def _validate_exchange(cls, v):
        """Validate exchange is supported by FMP."""
        if v is None:
            return v
        # Exchange stores MIC, FMP expects lowercase acronym
        exchange_code = v.acronym.lower()
        valid_exchanges = list(Exchanges.__args__)
        if exchange_code not in valid_exchanges:
            raise ValueError(
                f"Exchange '{v.name}' ({v.mic}) is not supported by FMP. "
                f"Valid options: {', '.join(sorted(valid_exchanges)[:20])}..."
            )
        return v


class FMPEquityScreenerData(EquityScreenerData):
    """FMP Equity Screener Data."""

    __alias_dict__ = {
        "name": "companyName",
        "market_cap": "marketCap",
        "last_annual_dividend": "lastAnnualDividend",
        "exchange": "exchangeShortName",
        "exchange_name": "exchange",
        "is_etf": "isEtf",
        "actively_trading": "isActivelyTrading",
    }

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Choose a supported exchange from the error message or from the Exchanges Literal in openbb_fmp.utils.references
  2. Omit exchange and filter returned rows by their exchange field client-side
  3. Catch the ValidationError and show the allowed exchange list in your UI/log

Example fix

# before
res = obb.screener.equity(provider='fmp', exchange='CHIX')  # MTF not supported by FMP

# after
res = obb.screener.equity(provider='fmp', exchange='NASDAQ')
# or post-filter
all_res = obb.screener.equity(provider='fmp')
chix_rows = [r for r in all_res.results if r.exchange and 'CHIX' in r.exchange]
Defensive patterns

Strategy: validation

Validate before calling

from openbb_fmp.utils.references import Exchanges
VALID_EXCHANGES = set(Exchanges.__args__)
exch_acronym = 'NASDAQ'  # derived from the Exchange object's acronym.lower()
if exch_acronym.lower() not in VALID_EXCHANGES:
    exchange = None

Type guard

def is_supported_fmp_exchange(acronym: str) -> bool:
    from openbb_fmp.utils.references import Exchanges
    return acronym.lower() in Exchanges.__args__

Try / catch

from pydantic import ValidationError
try:
    res = obb.screener.equity(provider='fmp', exchange=ex)
except ValidationError:
    res = obb.screener.equity(provider='fmp')  # filter returned rows by exchange client-side

Prevention

When it happens

Trigger: Calling obb.equity.screener(provider='fmp', exchange=...) with a valid MIC that has no FMP acronym mapping - obscure regional bourses, dark pools/MTFs (e.g. CHIX as an MTF code), or OTC venues.

Common situations: Porting screeners written against another data source with broader exchange coverage, MIC/acronym confusion (passing the MIC string where an Exchange is constructed, or vice versa), provider version changes to the Exchanges literal.

Related errors


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