OpenBB-finance/OpenBB · error · OpenBBError
Invalid choice. Choose from: ['all', 'agency debts', 'mbs',
Error message
Invalid choice. Choose from: ['all', 'agency debts', 'mbs', 'cmbs']
What it means
OpenBBError from SomaHoldings.get_agency_holdings: holding_type was supplied but is not a key in AGENCY_HOLDING_TYPES (accepted: 'all', 'agency debts', 'mbs', 'cmbs'). Raised before any URL is built, so it is pure input validation — note the message is a hardcoded string, not interpolated, so it always shows the same list.
Source
Thrown at openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/ny_fed_api.py:470
response: dict = {}
url: str = ""
dates = await self.get_as_of_dates()
if as_of is not None:
as_of = get_nearest_date(dates, as_of)
if as_of is None:
as_of = dates[0]
if wam is True:
url = _get_endpoints(
date=as_of,
)[
"soma_holdings"
]["agency_debts"]
response = await fetch_data(url)
return [response.get("soma", {})]
url = _get_endpoints(date=as_of)["soma_holdings"]["get_as_of"]
if holding_type is not None:
if holding_type not in AGENCY_HOLDING_TYPES:
raise OpenBBError(
"Invalid choice. Choose from: ['all', 'agency debts', 'mbs', 'cmbs']"
)
url = _get_endpoints(
agency_holding_type=AGENCY_HOLDING_TYPES[holding_type], date=as_of
)["soma_holdings"]["get_holding_type"]
if cusip is not None:
url = _get_endpoints(cusips=cusip)["soma_holdings"]["get_cusip"]
response = await fetch_data(url)
holdings = response.get("soma", {}).get("holdings", [])
if not holdings:
raise EmptyDataError()
return holdings
async def get_treasury_holdings( # pylint: disable=R0917
self,
as_of: str | None = None,
cusip: str | None = None,View on GitHub (pinned to 3e071fcc2c)
Solutions
- Use exactly one of: 'all', 'agency debts', 'mbs', 'cmbs' (lowercase, spaces not underscores).
- Normalize input: strip and lowercase, then check membership in the accepted set before calling.
- Pass holding_type=None to get all holdings unfiltered.
Example fix
// before holdings = await SomaHoldings().get_agency_holdings(holding_type='agency_debts') // after holdings = await SomaHoldings().get_agency_holdings(holding_type='agency debts')
Defensive patterns
Strategy: validation
Validate before calling
AGENCY_HOLDING_TYPES = {'all', 'agency debts', 'mbs', 'cmbs'}
holding_type = holding_type.strip().lower() if holding_type else None
assert holding_type is None or holding_type in AGENCY_HOLDING_TYPES Type guard
def is_valid_agency_holding_type(v) -> bool:
return v is None or (isinstance(v, str) and v.strip().lower() in {'all', 'agency debts', 'mbs', 'cmbs'}) Prevention
- Normalize (strip+lower) before submitting
- Remember labels use spaces, not underscores: 'agency debts'
When it happens
Trigger: Passing holding_type='agency_debts' (underscore instead of space), 'MBS' (case-sensitive lookup), 'cmo', or 'all ' (trailing space) to get_agency_holdings.
Common situations: Copy-pasting URL slugs or API query-param values instead of the human-readable labels; assuming case-insensitivity; trailing whitespace from config files.
Related errors
- Invalid choice. Choose from: {', '.join(TREASURY_HOLDING_TYP
- Incorrect email or password
- Error requesting dates. Please try again later.
- No data found. Try again later.
- There was an error with the request and was returned empty.
AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14).
Data as JSON: /api/errors/a3facd0265931224.
Report an issue: GitHub.