OpenBB-finance/OpenBB · error · OpenBBError

Invalid choice. Choose from: {', '.join(TREASURY_HOLDING_TYP

Error message

Invalid choice. Choose from: {', '.join(TREASURY_HOLDING_TYPES)}

What it means

OpenBBError from SomaHoldings.get_treasury_holdings: holding_type was supplied but is not in TREASURY_HOLDING_TYPES. Unlike the agency variant (377) this message is interpolated from the actual TREASURY_HOLDING_TYPES collection, so it reflects the real accepted values (typically 'bills', 'notes', 'bonds', 'frns', 'tips', 'cmbs' style labels).

Source

Thrown at openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/ny_fed_api.py:542

        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"
            ]["get_treasury_debts"]
            response = await fetch_data(url)
            return [response.get("soma", {})]

        if holding_type is not None:
            if holding_type not in TREASURY_HOLDING_TYPES:
                raise OpenBBError(
                    f"Invalid choice. Choose from: {', '.join(TREASURY_HOLDING_TYPES)}"
                )
            url = _get_endpoints(treasury_holding_type=holding_type, date=as_of)[
                "soma_holdings"
            ]["get_treasury_holding_type"]
        if monthly:
            url = _get_endpoints()["soma_holdings"]["get_treasury_monthly"]
        if cusip is not None:
            url = _get_endpoints(cusips=cusip)["soma_holdings"]["get_treasury_cusip"]

        response = await fetch_data(url)
        holdings = response.get("soma", {}).get("holdings", [])
        if not holdings:
            raise EmptyDataError()

        return holdings

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Use a value from the message's list exactly (case-sensitive match against TREASURY_HOLDING_TYPES).
  2. Normalize: strip/lower input and validate against the collection before calling.
  3. Pass holding_type=None for all treasury holdings.

Example fix

// before
h = await SomaHoldings().get_treasury_holdings(holding_type='bill')
// after
h = await SomaHoldings().get_treasury_holdings(holding_type='bills')  # exact key from TREASURY_HOLDING_TYPES
Defensive patterns

Strategy: validation

Validate before calling

from openbb_federal_reserve.utils.ny_fed_api import TREASURY_HOLDING_TYPES
holding_type = holding_type.strip().lower() if holding_type else None
assert holding_type is None or holding_type in TREASURY_HOLDING_TYPES, f'use: {", ".join(TREASURY_HOLDING_TYPES)}'

Type guard

def is_valid_treasury_holding_type(v, valid: set[str]) -> bool:
    return v is None or (isinstance(v, str) and v.strip().lower() in valid)

Prevention

When it happens

Trigger: Passing holding_type='bill' (singular), 'Notes' (wrong case), or a type valid for agency holdings but not treasuries to get_treasury_holdings.

Common situations: Reusing the agency holding-type vocabulary for treasury queries; singular/plural mismatches; case-sensitive lookups from unnormalized user input.

Related errors


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