ZhuLinsen/daily_stock_analysis · error · ValueError

market must be one of cn, hk, us, jp, kr, tw

Error message

market must be one of cn, hk, us, jp, kr, tw

What it means

ValueError from DecisionSignalService._normalize_market (src/services/decision_signal_service.py:1137): the market field is lowercased/stripped and must be one of VALID_MARKETS = {cn, hk, us, jp, kr, tw}. Anything else — including localized names like 'A股', 'china', exchange names, or case/typo variants not fixed by lowercasing — is rejected.

Source

Thrown at src/services/decision_signal_service.py:1137

        return code

    @staticmethod
    def _normalize_hk_stock_code(value: str) -> str:
        normalized = canonical_stock_code(normalize_stock_code(value))
        digits = ""
        if normalized.startswith("HK"):
            digits = normalized[2:]
        elif normalized.isdigit():
            digits = normalized
        if digits.isdigit() and 1 <= len(digits) <= 5:
            return f"HK{digits.zfill(5)}"
        return normalized

    @staticmethod
    def _normalize_market(value: Any) -> str:
        market = str(value or "").strip().lower()
        if market not in VALID_MARKETS:
            raise ValueError("market must be one of cn, hk, us, jp, kr, tw")
        return market

    @classmethod
    def _normalize_optional_market(cls, value: Any) -> Optional[str]:
        if value in (None, ""):
            return None
        return cls._normalize_market(value)

    @staticmethod
    def _normalize_action(value: Any) -> str:
        action = str(value or "").strip().lower()
        if not action or action not in DECISION_ACTIONS:
            raise ValueError("action must be one of buy/add/hold/reduce/sell/watch/avoid/alert")
        return action

    @classmethod
    def _normalize_optional_action(cls, value: Any) -> Optional[str]:
        if value in (None, ""):

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Map provider values to the six supported tokens before the call (CHN→cn, HKG/hkex→hk, USA/NASDAQ→us, JPY/japan→jp, KRW/korea→kr, TAIEX→tw).
  2. Use _normalize_optional_market / the API's optional field when market may be absent instead of sending placeholder strings.
  3. If you genuinely need an unsupported market, extend VALID_MARKETS and update docs/tests — do not bypass the check.
  4. Add a client-side enum guard (see validationCode).

Example fix

# before
service.create_signal({"stock_code": "00700", "market": "HKG", "action": "buy"})  # ValueError

# after
MARKET_MAP = {"CHN": "cn", "HKG": "hk", "USA": "us"}
market = MARKET_MAP.get(provider_market, provider_market.strip().lower())
service.create_signal({"stock_code": "00700", "market": "hk", "action": "buy"})
Defensive patterns

Strategy: type-guard

Validate before calling

VALID_MARKETS = {'cn', 'hk', 'us', 'jp', 'kr', 'tw'}
market = str(payload.get('market') or '').strip().lower()
if market not in VALID_MARKETS:
    raise ValueError(f'market must be one of {sorted(VALID_MARKETS)}')

Type guard

def is_valid_market(v) -> bool:
    return str(v or '').strip().lower() in {'cn', 'hk', 'us', 'jp', 'kr', 'tw'}

Prevention

When it happens

Trigger: create/update signal payloads with market: 'zh', 'CN ' (ok after trim/lower → 'cn'), 'a_share', 'sh', 'hongkong', 'USA', 'japan', 'TSE', or None/'' when market is required. _normalize_optional_market tolerates None but any non-empty wrong value hits this error.

Common situations: Mapping from a provider that uses ISO country codes (CHN/HKG/USA) or exchange codes (SH/SZ/HKEX/NASDAQ) directly to market; locale-dependent labels; adding a new market to the enum without updating callers; data pipelines forwarding the stock's currency ('CNY'/'HKD') as market.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/396128877e529fb2. Report an issue: GitHub.