HKUDS/Vibe-Trading · error · ValueError

weights missing basket symbols: {sorted(missing)}

Error message

weights missing basket symbols: {sorted(missing)}

What it means

Raised by PortfolioRiskTool._parse_weights when the user-supplied weights mapping does not include an entry for every symbol in the basket. The tool requires weights to be complete: keys must exactly equal the basket symbol set (no unknowns, no omissions). Missing keys make portfolio weights impossible to normalize, so it fails fast with the sorted list of omitted symbols.

Source

Thrown at agent/src/tools/portfolio_risk_tool.py:145

                "source": source,
                "unresolved_symbols": list(unresolved or []),
            },
        }
        return json.dumps(envelope, ensure_ascii=False, indent=2, allow_nan=False)

    # ------------------------------------------------------------------
    @staticmethod
    def _parse_weights(raw: Any, symbols: list[str]) -> dict[str, float]:
        if raw is None:
            return {sym: 1.0 / len(symbols) for sym in symbols}
        if not isinstance(raw, Mapping):
            raise ValueError("weights must be an object mapping symbol → number")
        unknown = [sym for sym in raw if sym not in symbols]
        if unknown:
            raise ValueError(f"weights name symbols not in the basket: {sorted(unknown)}")
        missing = [sym for sym in symbols if sym not in raw]
        if missing:
            raise ValueError(f"weights missing basket symbols: {sorted(missing)}")
        return {sym: raw[sym] for sym in symbols}

    @staticmethod
    def _parse_dates(start_raw: Any, end_raw: Any) -> tuple[str, str]:
        end = (
            datetime.strptime(end_raw, "%Y-%m-%d").date()
            if isinstance(end_raw, str) and end_raw
            else datetime.now(timezone.utc).date()
        )
        start = (
            datetime.strptime(start_raw, "%Y-%m-%d").date()
            if isinstance(start_raw, str) and start_raw
            else end - timedelta(days=_DEFAULT_LOOKBACK_DAYS)
        )
        if start >= end:
            raise ValueError(f"start_date {start} must be before end_date {end}")
        return start.isoformat(), end.isoformat()

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Add the listed missing symbols to the weights object so its keys exactly match the basket symbols
  2. Check for whitespace/case mismatches in symbol keys (e.g. 'aapl' vs 'AAPL') that cause symbols to be seen as missing
  3. Assign 0.0 to symbols you want to exclude rather than omitting them
  4. If symbols are unknown too, fix those first — the unknown-symbol check runs before this one

Example fix

# before
weights = {"AAPL": 0.5, "MSFT": 0.5}  # basket is AAPL, MSFT, NVDA

# after
weights = {"AAPL": 0.5, "MSFT": 0.3, "NVDA": 0.2}
Defensive patterns

Strategy: validation

Validate before calling

basket = set(symbols)
weights_keys = set(weights)
missing = basket - weights_keys
unknown = weights_keys - basket
if missing or unknown:
    raise ValueError(f"weights mismatch: missing={sorted(missing)}, unknown={sorted(unknown)}")
weights = {s: float(weights.get(s, 0.0)) for s in symbols}

Type guard

def valid_weights(weights: object, symbols: list[str]) -> bool:
    return (
        isinstance(weights, dict)
        and set(weights) == set(symbols)
        and all(isinstance(v, (int, float)) for v in weights.values())
    )

Try / catch

try:
    result = portfolio_risk_tool.run(...)
except ValueError as e:
    if "weights" in str(e):
        weights = {s: float(raw_weights.get(s, 0.0)) for s in symbols}  # backfill and retry

Prevention

When it happens

Trigger: Calling the portfolio risk tool with a weights object whose keys are a strict subset of the basket symbols, e.g. basket ['AAPL','MSFT','NVDA'] with weights {'AAPL':0.5}. Also happens when a symbol name has a typo or different casing so it is treated as 'unknown' first, or after whitespace differences like 'AAPL ' vs 'AAPL'.

Common situations: LLM-generated tool calls that fabricate partial weight maps; users copy-pasting weights from a spreadsheet that drops zero-weight rows; baskets changed server-side while the caller cached an old symbol list.

Related errors


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