HKUDS/Vibe-Trading · error · ValueError
too many symbols ({len(symbols)}); cap is {_MAX_SYMBOLS}
Error message
too many symbols ({len(symbols)}); cap is {_MAX_SYMBOLS} What it means
After symbol validation, _run enforces the basket size cap _MAX_SYMBOLS; exceeding it raises with the actual count and the cap value so the caller knows how much to trim.
Source
Thrown at agent/src/tools/portfolio_risk_tool.py:102
def execute(self, **kwargs: Any) -> str:
try:
return self._run(**kwargs)
except Exception as exc: # noqa: BLE001 — tool must always return JSON
logger.warning("portfolio_risk_xray failed: %s", exc)
return json.dumps(
{"status": "error", "error": str(exc)}, ensure_ascii=False, allow_nan=False
)
# ------------------------------------------------------------------
def _run(self, **kwargs: Any) -> str:
symbols = kwargs.get("symbols")
if not isinstance(symbols, list) or not symbols or not all(
isinstance(s, str) and s.strip() for s in symbols
):
raise ValueError("symbols must be a non-empty list of strings")
symbols = [s.strip() for s in symbols]
if len(symbols) > _MAX_SYMBOLS:
raise ValueError(f"too many symbols ({len(symbols)}); cap is {_MAX_SYMBOLS}")
weights = self._parse_weights(kwargs.get("weights"), symbols)
start_date, end_date = self._parse_dates(kwargs.get("start_date"), kwargs.get("end_date"))
source = str(kwargs.get("source") or "auto")
interval = str(kwargs.get("interval") or "1D")
raw = self._fetch(
codes=symbols,
start_date=start_date,
end_date=end_date,
source=source,
interval=interval,
)
closes = self._closes_frame(raw, symbols)
unresolved = raw.get("_unresolved") if isinstance(raw, Mapping) else None
report = compute_risk_xray(closes, weights)
envelope = {View on GitHub (pinned to 80ffdda44c)
Solutions
- Trim to the cap (prioritize highest-conviction/highest-liquidity names)
- Batch into multiple calls and aggregate results if supported
- Read the cap from the error message or module constant
Example fix
# before execute(symbols=all_500_tickers) # after execute(symbols=all_500_tickers[:_MAX_SYMBOLS])
Defensive patterns
Strategy: validation
Validate before calling
from agent.src.tools.portfolio_risk_tool import _MAX_SYMBOLS
if len(symbols) > _MAX_SYMBOLS:
symbols = symbols[:_MAX_SYMBOLS] # or batch Type guard
def within_symbol_cap(syms: list[str], cap: int) -> bool:
return len(syms) <= cap Try / catch
try:
out = tool.execute(symbols=symbols)
except ValueError as e:
if "cap is" in str(e):
out = tool.execute(symbols=symbols[:_MAX_SYMBOLS]) Prevention
- Trim watchlists before analysis
- Batch large universes into multiple calls
- Read the cap from the error message or module constant
When it happens
Trigger: Passing more than _MAX_SYMBOLS symbols, e.g. an entire index constituent list.
Common situations: Backtesting whole universes instead of baskets, unioning watchlists, or LLMs pasting long ticker lists.
Related errors
- symbols must be a non-empty list of strings
- at most 50 portfolio sources are allowed
- weights must be an object mapping symbol → number
- weights name symbols not in the basket: {sorted(unknown)}
- weights missing basket symbols: {sorted(missing)}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/b1065518ec450bc2.
Report an issue: GitHub.