{"record":{"id":"cffb72b4d61d2620","repo":"OpenBB-finance/OpenBB","slug":"invalid-exchange-value-accepts-iso-10383-mic","errorCode":null,"errorMessage":"Invalid exchange: '{value}'. Accepts ISO 10383 MIC codes (e.g., 'XNAS', 'XNYS'), acronyms (e.g., 'NASDAQ', 'NYSE'), or exchange names (e.g., 'New York Stock Exchange').","messagePattern":"Invalid exchange: '(.+?)'\\. Accepts ISO 10383 MIC codes \\(e\\.g\\., 'XNAS', 'XNYS'\\), acronyms \\(e\\.g\\., 'NASDAQ', 'NYSE'\\), or exchange names \\(e\\.g\\., 'New York Stock Exchange'\\)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/core/openbb_core/provider/utils/exchange_utils.py","lineNumber":173,"sourceCode":"\n        # Convert lower_snake_case to lookup key\n        if \"_\" in val:\n            val = val.replace(\"_\", \" \")\n\n        # Try direct lookup\n        lookup_key = val.lower()\n        if lookup_key in _EXCHANGE_LOOKUP:\n            return _EXCHANGE_LOOKUP[lookup_key]\n\n        # Try uppercase (common for MICs)\n        if val.upper() in _EXCHANGE_LOOKUP:\n            return _EXCHANGE_LOOKUP[val.upper()]\n\n        # Try original case\n        if val in _EXCHANGE_LOOKUP:\n            return _EXCHANGE_LOOKUP[val]\n\n        raise ValueError(\n            f\"Invalid exchange: '{value}'. \"\n            \"Accepts ISO 10383 MIC codes (e.g., 'XNAS', 'XNYS'), \"\n            \"acronyms (e.g., 'NASDAQ', 'NYSE'), \"\n            \"or exchange names (e.g., 'New York Stock Exchange').\"\n        )\n\n    @property\n    def mic(self) -> str:\n        \"\"\"ISO 10383 Market Identifier Code (e.g., 'XNAS').\"\"\"\n        return self._exchange_data[\"mic\"]\n\n    @property\n    def acronym(self) -> str:\n        \"\"\"Exchange acronym/short name (e.g., 'NASDAQ').\"\"\"\n        return self._exchange_data[\"acronym\"]\n\n    @property\n    def name(self) -> str:","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/core/openbb_core/provider/utils/exchange_utils.py#L155-L191","documentation":"Raised by Exchange.__new__._lookup_exchange (exchange_utils.py) when the value cannot be resolved in the ISO 10383 lookup table. It tries lowercase, uppercase, and original-case forms of MIC codes ('XNAS'), acronyms ('NASDAQ'), and exchange names; failure raises this ValueError. Exchange is a Pydantic annotated type, so it fires during validation wherever an 'exchange' parameter is normalized.","triggerScenarios":"Passing a non-MIC ticker-ish string ('NYSE:AAPL' instead of 'XNYS'), an unknown acronym ('TSX' may map, 'LSE' depends on table), a deprecated/operating-status-excluded MIC, or a non-string value that fails all three dict lookups.","commonSituations":"Copying exchange identifiers from other APIs (Yahoo/Reuters codes like 'NMS' or 'NYSE'), using composite 'symbol:exchange' strings, or MICs retired by ISO 10383 updates after the packaged table was generated.","solutions":["Use the official ISO 10383 MIC (operating MIC): 'XNAS' for NASDAQ, 'XNYS' for NYSE, 'XLON' for London","Or a well-known acronym/name: 'NASDAQ', 'New York Stock Exchange'","Search the packaged table to confirm what is accepted: from openbb_core.provider.utils.exchange_utils import _EXCHANGE_LOOKUP; [k for k in _EXCHANGE_LOOKUP if 'nasdaq' in k]","If the MIC is legitimately missing, regenerate the exchange data via openbb_core.provider.utils.update_exchange_data or file an issue"],"exampleFix":"# before\nres = await obb.equity.price.quote(symbol=\"AAPL\")  # with exchange=\"NMS\" -> ValueError (Yahoo-style code)\n\n# after\nres = await obb.equity.price.quote(symbol=\"AAPL\")  # with exchange=\"XNAS\" (ISO 10383 MIC)","handlingStrategy":"validation","validationCode":"from openbb_core.provider.utils.exchange_utils import _EXCHANGE_LOOKUP\n\ndef is_known_exchange(v: str) -> bool:\n    return v.lower() in _EXCHANGE_LOOKUP or v.upper() in _EXCHANGE_LOOKUP or v in _EXCHANGE_LOOKUP\n\nif not is_known_exchange(exchange):\n    exchange = \"XNAS\"  # or strip 'SYM:EXCH' composites first","typeGuard":"def is_mic_like(v: str) -> bool:\n    return len(v) == 4 and v.isalpha() and v.isupper()","tryCatchPattern":"from pydantic import ValidationError\n\ntry:\n    res = await obb.equity.price.quote(symbol=sym, exchange=exchange)\nexcept ValidationError as e:\n    if any(\"Invalid exchange\" in str(err[\"msg\"]) for err in e.errors()):\n        res = await obb.equity.price.quote(symbol=sym)  # retry without exchange\n    else:\n        raise","preventionTips":["Canonicalize to ISO 10383 MICs in your data store; treat vendor codes (NMS, LSE) as aliases to translate at ingest","Split composite 'symbol:exchange' strings before passing either part to OpenBB","Keep a curated alias table and validate against _EXCHANGE_LOOKUP before requests"],"tags":["validation","iso-10383","mic","exchange","pydantic"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}