HKUDS/Vibe-Trading · error · ValueError
portfolio_weights cannot be empty
Error message
portfolio_weights cannot be empty
What it means
factor_risk_decomposition refuses an empty portfolio_weights input because risk of nothing is undefined (and downstream linear algebra would fail anyway).
Source
Thrown at agent/src/quantlib/factormodel.py:634
Args:
portfolio_weights: Asset weights in the portfolio.
exposures: Asset factor exposures (rows = assets, columns = factors).
factor_cov: Covariance matrix of factor returns (K x K).
specific_variances: Asset-specific (idiosyncratic) return variances.
Defaults to zero if omitted.
Returns:
:class:`FactorRiskDecomposition` containing total/factor/specific
variances, volatilities, marginal contributions to risk (MCR), and
percentage contributions to risk (PCR) per factor and per asset.
Raises:
ValueError: If weights or matrices are empty, contain non-finite values,
or share no common assets or factors.
"""
w_series = pd.Series(portfolio_weights, dtype=float)
if w_series.empty:
raise ValueError("portfolio_weights cannot be empty")
if not np.isfinite(w_series.values).all():
raise ValueError("portfolio_weights contains non-finite values")
if not isinstance(exposures, pd.DataFrame) or exposures.empty:
raise ValueError("exposures must be a non-empty DataFrame")
if not np.isfinite(exposures.values).all():
raise ValueError("exposures contains non-finite values")
if not isinstance(factor_cov, pd.DataFrame) or factor_cov.empty:
raise ValueError("factor_cov must be a non-empty DataFrame")
if not np.isfinite(factor_cov.values).all():
raise ValueError("factor_cov contains non-finite values")
# Align assets
assets = w_series.index.intersection(exposures.index)
if assets.empty:
raise ValueError(
f"No matching assets between weights ({sorted(w_series.index)}) and exposures ({sorted(exposures.index)})"View on GitHub (pinned to 80ffdda44c)
Solutions
- Check len(portfolio_weights) before calling
- Log the portfolio ID/weights source when it comes up empty
- Return a zero-risk result upstream instead of calling the API
Example fix
# before risk = factor_risk_decomposition(w, X, F) # after risk = factor_risk_decomposition(w, X, F) if len(w) else None
Defensive patterns
Strategy: validation
Validate before calling
assert len(portfolio_weights) > 0
Prevention
- Guard nightly jobs with an empty-book check
- Return structured zero-risk result instead of calling the API
When it happens
Trigger: Passing portfolio_weights={}, an empty list, or an empty pd.Series.
Common situations: Empty book passed to a nightly risk job; positions filtered out by a universe screen before the call.
Related errors
- holdings is empty
- exposures has no factor columns
- brinson_fachler needs at least one sector
- style drift needs at least 2 dates, got {exposure_history.sh
- portfolio_weights contains non-finite values
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/7680647240229792.
Report an issue: GitHub.