{"record":{"id":"6893e796a61ba528","repo":"HKUDS/Vibe-Trading","slug":"factor-cov-must-be-a-non-empty-dataframe","errorCode":null,"errorMessage":"factor_cov must be a non-empty DataFrame","messagePattern":"factor_cov must be a non-empty DataFrame","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/factormodel.py","lineNumber":644,"sourceCode":"        percentage contributions to risk (PCR) per factor and per asset.\n\n    Raises:\n        ValueError: If weights or matrices are empty, contain non-finite values,\n            or share no common assets or factors.\n    \"\"\"\n    w_series = pd.Series(portfolio_weights, dtype=float)\n    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(","sourceCodeStart":626,"sourceCodeEnd":662,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/factormodel.py#L626-L662","documentation":"factor_cov must be a non-empty square pandas DataFrame of factor covariances. A Series, ndarray, dict, or empty frame fails this isinstance/empty check.","triggerScenarios":"factor_cov=np.cov(returns) (ndarray), a dict of variances, or pd.DataFrame() passed as third argument.","commonSituations":"Covariance estimated with numpy directly instead of pandas; a loader returned {} on failure; refactor changed the return type.","solutions":["Wrap ndarray output: pd.DataFrame(cov, index=factors, columns=factors)","Ensure the factor list used for the index matches exposures.columns","Fix the loader that returned an empty frame"],"exampleFix":"# before\nrisk = factor_risk_decomposition(w, X, np.cov(R))\n# after\nF = pd.DataFrame(np.cov(R), index=factors, columns=factors)\nrisk = factor_risk_decomposition(w, X, F)","handlingStrategy":"type-guard","validationCode":"assert isinstance(factor_cov, pd.DataFrame) and not factor_cov.empty","typeGuard":"def is_cov_frame(x) -> bool:\n    return (isinstance(x, pd.DataFrame) and not x.empty\n            and x.shape[0] == x.shape[1])","tryCatchPattern":null,"preventionTips":["Always construct covariance with index=columns=factors","Wrap ndarray covariance output in a DataFrame immediately"],"tags":["quantlib","factormodel","type-validation","covariance"],"backgroundTag":"wrong-argument-type","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}