{"record":{"id":"377ec30f5b6c2584","repo":"HKUDS/Vibe-Trading","slug":"sec-investment-company-series-class-index-unavaila","errorCode":null,"errorMessage":"SEC investment-company series/class index unavailable ({'; '.join(failures)})","messagePattern":"SEC investment-company series/class index unavailable \\((.+?)\\)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/etf_holdings_tool.py","lineNumber":439,"sourceCode":"    if _US_INDEX_CACHE is not None:\n        return _US_INDEX_CACHE\n    with _US_INDEX_LOCK:\n        if _US_INDEX_CACHE is None:\n            this_year = date.today().year\n            failures: list[str] = []\n            for year in (this_year, this_year - 1):\n                try:\n                    body = _sec_get_text(_SEC_SERIES_INDEX_URL.format(year=year))\n                except Exception as exc:  # noqa: BLE001 - try the older vintage\n                    failures.append(f\"{year}: {exc}\")\n                    continue\n                records = _parse_series_index(body)\n                if records:\n                    _US_INDEX_CACHE = (year, records)\n                    break\n                failures.append(f\"{year}: index parsed to zero rows\")\n            else:\n                raise RuntimeError(\n                    \"SEC investment-company series/class index unavailable (\"\n                    + \"; \".join(failures)\n                    + \")\"\n                )\n    return _US_INDEX_CACHE\n\n\ndef _is_etf_class(record: dict[str, Any]) -> bool:\n    \"\"\"Report whether an index row looks like an exchange-traded share class.\n\n    The SEC series/class file has no ETF flag, so the only available signal is\n    the wording: an ETF is named one either in its series name (``iShares\n    Semiconductor ETF``) or in its class name (VOO is ``ETF Shares`` of the\n    ``Vanguard 500 Index Fund``). This is a ranking heuristic only — nothing is\n    dropped on the strength of it, and the underlying names are returned so the\n    caller can judge for itself.\n\n    Args:","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/etf_holdings_tool.py#L421-L457","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Retry after a delay and verify https://sec.gov is reachable from the environment","Set a proper declared User-Agent per SEC fair-access policy if the fetch layer allows it","Check whether the series/class index URL or format changed and patch _parse_series_index / widen the fallback years","If long-running, clear _US_INDEX_CACHE is not needed (only set on success), but restart to drop any transient state"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        holdings = _lookup_us(cik)\n        break\n    except RuntimeError as exc:\n        if \"series/class index unavailable\" in str(exc) and attempt < 2:\n            time.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Throttle requests to sec.gov (<=10/sec, declare a contact User-Agent)","Cache the series/class index locally since it changes rarely","Monitor SEC status/format changes; widen the year fallback window when SEC publishes late"],"tags":["network","sec-edgar","upstream-data","runtime-error","python"],"backgroundTag":"upstream-api-unavailable","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}