{"record":{"id":"ab3f7486a0dfc00d","repo":"HKUDS/Vibe-Trading","slug":"no-matching-assets-between-weights-sorted-w-seri","errorCode":null,"errorMessage":"No matching assets between weights ({sorted(w_series.index)}) and exposures ({sorted(exposures.index)})","messagePattern":"No matching assets between weights \\((.+?)\\) and exposures \\((.+?)\\)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/factormodel.py","lineNumber":651,"sourceCode":"    if w_series.empty:\n        raise ValueError(\"portfolio_weights cannot be empty\")\n    if not np.isfinite(w_series.values).all():\n        raise ValueError(\"portfolio_weights contains non-finite values\")\n\n    if not isinstance(exposures, pd.DataFrame) or exposures.empty:\n        raise ValueError(\"exposures must be a non-empty DataFrame\")\n    if not np.isfinite(exposures.values).all():\n        raise ValueError(\"exposures contains non-finite values\")\n\n    if not isinstance(factor_cov, pd.DataFrame) or factor_cov.empty:\n        raise ValueError(\"factor_cov must be a non-empty DataFrame\")\n    if not np.isfinite(factor_cov.values).all():\n        raise ValueError(\"factor_cov contains non-finite values\")\n\n    # Align assets\n    assets = w_series.index.intersection(exposures.index)\n    if assets.empty:\n        raise ValueError(\n            f\"No matching assets between weights ({sorted(w_series.index)}) and exposures ({sorted(exposures.index)})\"\n        )\n\n    unmatched_weight = float(w_series.drop(index=assets, errors=\"ignore\").abs().sum())\n    w = w_series.loc[assets]\n    X = exposures.loc[assets]\n\n    # Align factors\n    factors = X.columns.intersection(factor_cov.index).intersection(factor_cov.columns)\n    if factors.empty:\n        raise ValueError(\n            f\"No matching factors between exposures ({sorted(X.columns)}) and factor_cov ({sorted(factor_cov.index)})\"\n        )\n\n    X = X[factors]\n    F = factor_cov.loc[factors, factors]\n    F_mat = F.to_numpy(dtype=float)\n    if not np.allclose(F_mat, F_mat.T, atol=1e-8):","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/factormodel.py#L633-L669","documentation":"Weights are aligned to exposures by asset (row) index; if w_series.index and exposures.index share no ticker, there is nothing to risk-decompose and the message prints both sets to expose the mismatch.","triggerScenarios":"Weights keyed 'AAPL US Equity' vs exposures 'AAPL'; CUSIP vs ticker identifiers; weights from a different universe than the exposure file.","commonSituations":"Security-master identifier mismatch between the portfolio system and the risk model vendor file.","solutions":["Compare the two sorted index lists shown in the message","Normalize identifiers (strip suffixes, map via security master) before the call","Reindex exposures onto the weights' tickers after mapping"],"exampleFix":"# before\nrisk = factor_risk_decomposition(w, X, F)\n# after\nX = X.rename(index=sec_master_map)  # align identifiers\nrisk = factor_risk_decomposition(w, X, F)","handlingStrategy":"validation","validationCode":"assert w_series.index.intersection(exposures.index).size > 0","typeGuard":null,"tryCatchPattern":"try:\n    risk = factor_risk_decomposition(w, X, F)\nexcept ValueError as e:\n    if 'No matching assets' in str(e):\n        log_identifiers(w.index, X.index)\n    raise","preventionTips":["Maintain a security-master identifier map","Assert overlap ratio > 0.8 before full runs"],"tags":["quantlib","factormodel","index-alignment","identifiers"],"backgroundTag":"disjoint-index-alignment","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}