ZhuLinsen/daily_stock_analysis · error · IntelligenceServiceError

unsupported scope_type: {scope_type}

Error message

unsupported scope_type: {scope_type}

What it means

Validation in _normalize_source_fields: scope_type (default 'market', lowercased) is not in _ALLOWED_SCOPE_TYPES = {'symbol','market','sector'}. The scope controls how fetched intelligence items are attached (whole market, one ticker, or a sector).

Source

Thrown at src/services/intelligence_service.py:376

        return result

    def _normalize_source_fields(self, payload: Dict[str, Any]) -> Dict[str, Any]:
        name = str(payload.get("name") or "").strip()
        url = str(payload.get("url") or "").strip()
        source_type = str(payload.get("source_type") or "rss").strip().lower()
        scope_type = str(payload.get("scope_type") or "market").strip().lower()
        scope_value = str(payload.get("scope_value") or "").strip() or None
        market = str(payload.get("market") or "cn").strip().lower()
        enabled = bool(payload.get("enabled", True))
        description = str(payload.get("description") or "").strip() or None
        if not name:
            raise IntelligenceServiceError("source name is required")
        if not url:
            raise IntelligenceServiceError("source url is required")
        if source_type not in _ALLOWED_SOURCE_TYPES:
            raise IntelligenceServiceError(f"unsupported source_type: {source_type}")
        if scope_type not in _ALLOWED_SCOPE_TYPES:
            raise IntelligenceServiceError(f"unsupported scope_type: {scope_type}")
        if scope_type in {"symbol", "sector"} and not scope_value:
            raise IntelligenceServiceError(f"scope_value is required when scope_type={scope_type}")
        if market not in _ALLOWED_MARKETS:
            raise IntelligenceServiceError(f"unsupported market: {market}")
        return {
            "name": name[:100],
            "source_type": source_type,
            "url": url,
            "enabled": enabled,
            "scope_type": scope_type,
            "scope_value": scope_value[:64] if scope_value else None,
            "market": market,
            "description": description,
        }

    def _validate_url(self, raw_url: str, *, allow_no_url: bool = False) -> None:
        if allow_no_url and raw_url.startswith("no-url:intel:"):
            return

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Use one of: market, symbol, sector (case-insensitive)
  2. Remember scope_value is required when scope_type is symbol or sector — supply it in the same request
  3. Align client-side enums with the backend allowed set

Example fix

# before
svc.create_source({'name':'x','url':'...','scope_type':'global'})
# after
svc.create_source({'name':'x','url':'...','scope_type':'market','market':'global'})
Defensive patterns

Strategy: type-guard

Validate before calling

ALLOWED = {'symbol', 'market', 'sector'}
scope_type = str(payload.get('scope_type') or 'market').strip().lower()
if scope_type not in ALLOWED:
    raise UserError(f'scope_type 仅支持 {sorted(ALLOWED)}')
if scope_type in ('symbol', 'sector') and not (payload.get('scope_value') or '').strip():
    raise UserError(f'scope_value 必填 when scope_type={scope_type}')

Type guard

def is_valid_scope_payload(p: dict) -> bool:
    st = str(p.get('scope_type') or 'market').strip().lower()
    if st not in {'symbol', 'market', 'sector'}:
        return False
    return st == 'market' or bool(str(p.get('scope_value') or '').strip())

Try / catch

try:
    svc.create_source(payload)
except IntelligenceServiceError as e:
    if 'unsupported scope_type' in str(e):
        payload['scope_type'] = 'market'
        payload.pop('scope_value', None)
        svc.create_source(payload)
    else:
        raise

Prevention

When it happens

Trigger: POSTing scope_type like 'global', 'watchlist', 'industry', or 'Market ' with stray characters.

Common situations: Frontend dropdown built with extra options; consumer assuming a 'global' scope exists (the market value 'global' is a different field — market); typos/case handled by lower() but whitespace-only variants fail.

Related errors


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