HKUDS/Vibe-Trading · error · ValueError

display_currency must be USD or CNY

Error message

display_currency must be USD or CNY

What it means

PortfolioSettings parsing rejects display_currency values other than USD or CNY (case-insensitive after strip+upper). The display currency drives all reporting/FX conversion, so only these two are supported.

Source

Thrown at agent/src/portfolio/config.py:148

) -> PortfolioSettings:
    """Validate untrusted Web settings against the local connection registry.

    Args:
        payload: Raw settings dict from the Web UI, CLI or a settings file.
        connection_store: Local connection registry; a default store is used
            when omitted.

    Returns:
        Validated, order-normalized settings.

    Raises:
        ValueError: If the display currency, the source list, a connection id,
            a label, or a referenced profile's eligibility is invalid.
    """
    store = connection_store or ConnectionStore()
    currency = str(payload.get("display_currency") or "USD").strip().upper()
    if currency not in {"USD", "CNY"}:
        raise ValueError("display_currency must be USD or CNY")

    raw_sources = payload.get("sources")
    if not isinstance(raw_sources, list):
        raise ValueError("sources must be a list")
    if len(raw_sources) > 50:
        raise ValueError("at most 50 portfolio sources are allowed")

    seen_ids: set[str] = set()
    sources: list[PortfolioSource] = []
    for index, raw in enumerate(raw_sources):
        if not isinstance(raw, dict):
            raise ValueError("each portfolio source must be an object")
        connection_id = (
            str(raw.get("connection_id") or raw.get("id") or "").strip().lower()
        )
        if not _SOURCE_ID_RE.fullmatch(connection_id):
            raise ValueError(f"invalid portfolio connection id: {connection_id or '?'}")
        legacy_profile_id = str(raw.get("profile_id") or "").strip().lower()

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Set display_currency to 'USD' or 'CNY' (any case; it is normalized)
  2. Omit the field entirely — it defaults to USD
  3. Extend the allowed set only if you also implement the required FX conversion

Example fix

# before
{"display_currency": "EUR"}
# after
{"display_currency": "USD"}
Defensive patterns

Strategy: validation

Validate before calling

currency = str(payload.get('display_currency') or 'USD').strip().upper()
if currency not in {'USD', 'CNY'}:
    payload['display_currency'] = 'USD'  # or surface an error to the user

Type guard

def is_supported_currency(c) -> bool:
    return isinstance(c, str) and c.strip().upper() in {'USD', 'CNY'}

Try / catch

try:
    settings = store.load()
except ValueError as exc:
    if 'display_currency' in str(exc):
        payload['display_currency'] = 'USD'
        settings = store.parse_settings(payload, store.connection_store)

Prevention

When it happens

Trigger: parse_settings({'display_currency': 'EUR'}) or 'usd ' works but 'eur', 'yen', '' after normalization to non-USD/CNY fails; loading a settings file with an unsupported currency via load().

Common situations: Hand-edited portfolio settings JSON, users in other locales assuming arbitrary ISO codes are supported, or currency keys copied from a different config schema.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/c8a9a90aa91fa2e2. Report an issue: GitHub.