HKUDS/Vibe-Trading · error · RuntimeError

SEC investment-company series/class index unavailable ({'; '

Error message

SEC investment-company series/class index unavailable ({'; '.join(failures)})

What it means

The tool tries to download and parse the SEC investment-company series/class index for recent years (with fallback to earlier years, cached). If every attempted year yields no parseable rows, it raises this RuntimeError listing each failure. This is a network/upstream data error, not an input error.

Source

Thrown at agent/src/tools/etf_holdings_tool.py:439

    if _US_INDEX_CACHE is not None:
        return _US_INDEX_CACHE
    with _US_INDEX_LOCK:
        if _US_INDEX_CACHE is None:
            this_year = date.today().year
            failures: list[str] = []
            for year in (this_year, this_year - 1):
                try:
                    body = _sec_get_text(_SEC_SERIES_INDEX_URL.format(year=year))
                except Exception as exc:  # noqa: BLE001 - try the older vintage
                    failures.append(f"{year}: {exc}")
                    continue
                records = _parse_series_index(body)
                if records:
                    _US_INDEX_CACHE = (year, records)
                    break
                failures.append(f"{year}: index parsed to zero rows")
            else:
                raise RuntimeError(
                    "SEC investment-company series/class index unavailable ("
                    + "; ".join(failures)
                    + ")"
                )
    return _US_INDEX_CACHE


def _is_etf_class(record: dict[str, Any]) -> bool:
    """Report whether an index row looks like an exchange-traded share class.

    The SEC series/class file has no ETF flag, so the only available signal is
    the wording: an ETF is named one either in its series name (``iShares
    Semiconductor ETF``) or in its class name (VOO is ``ETF Shares`` of the
    ``Vanguard 500 Index Fund``). This is a ranking heuristic only — nothing is
    dropped on the strength of it, and the underlying names are returned so the
    caller can judge for itself.

    Args:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Retry after a delay and verify https://sec.gov is reachable from the environment
  2. Set a proper declared User-Agent per SEC fair-access policy if the fetch layer allows it
  3. Check whether the series/class index URL or format changed and patch _parse_series_index / widen the fallback years
  4. If long-running, clear _US_INDEX_CACHE is not needed (only set on success), but restart to drop any transient state
Defensive patterns

Strategy: retry

Try / catch

for attempt in range(3):
    try:
        holdings = _lookup_us(cik)
        break
    except RuntimeError as exc:
        if "series/class index unavailable" in str(exc) and attempt < 2:
            time.sleep(2 ** attempt)
            continue
        raise

Prevention

When it happens

Trigger: SEC.gov returning empty/error HTML instead of the index (rate limiting, UA blocking), a changed file layout that makes _parse_series_index return zero rows, or offline/proxied environments — for all candidate years in the loop.

Common situations: Running the tool in CI behind a proxy that blocks sec.gov; SEC applies 403 rate limits to non-declared user agents; SEC restructures the series/class CSV so parsing yields nothing; the fallback-year window is exhausted.

Related errors


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