{"record":{"id":"cfa1542358c4cbde","repo":"HKUDS/Vibe-Trading","slug":"no-matching-factors-between-exposures-sorted-x-c","errorCode":null,"errorMessage":"No matching factors between exposures ({sorted(X.columns)}) and factor_cov ({sorted(factor_cov.index)})","messagePattern":"No matching factors between exposures \\((.+?)\\) and factor_cov \\((.+?)\\)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/factormodel.py","lineNumber":662,"sourceCode":"        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):\n        raise ValueError(\"factor_cov matrix must be symmetric\")\n    eigvals = np.linalg.eigvalsh(F_mat)\n    if np.min(eigvals) < -1e-8:\n        raise ValueError(\"factor_cov matrix must be positive semi-definite\")\n\n    # Align specific variances\n    if specific_variances is not None:\n        spec_var_s = pd.Series(specific_variances, dtype=float)\n        if not np.isfinite(spec_var_s.values).all():\n            raise ValueError(\"specific_variances contains non-finite values\")\n        d = spec_var_s.reindex(assets, fill_value=0.0).clip(lower=0.0)","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/factormodel.py#L644-L680","documentation":"Factor columns of exposures are intersected with factor_cov's index and columns; an empty intersection (different factor taxonomies) makes the decomposition impossible and the error lists both sets.","triggerScenarios":"Exposures with columns ['momentum','value'] but factor_cov indexed by ['MOM','VAL']; covariance built from a different factor model version.","commonSituations":"Risk model was upgraded/renamed factors; exposures and covariance pulled from different model snapshots.","solutions":["Diff the two factor-name lists printed in the message","Rename columns/index to a shared taxonomy before calling","Regenerate both from the same factor model run"],"exampleFix":"# before\nrisk = factor_risk_decomposition(w, X, F)\n# after\nX = X.rename(columns=name_map)\nF = F.rename(index=name_map, columns=name_map)\nrisk = factor_risk_decomposition(w, X, F)","handlingStrategy":"validation","validationCode":"assert X.columns.intersection(F.index).size > 0","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate exposures and covariance from the same model snapshot","Version-pin factor taxonomies in config"],"tags":["quantlib","factormodel","index-alignment","factors"],"backgroundTag":"disjoint-index-alignment","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}