{"record":{"id":"9b354e8ccf078079","repo":"HKUDS/Vibe-Trading","slug":"alpha-id-compute-returned-type-result-nam","errorCode":null,"errorMessage":"{alpha_id}: compute() returned {type(result).__name__}, expected DataFrame","messagePattern":"(.+?): compute\\(\\) returned (.+?), expected DataFrame","errorType":"validation","errorClass":"RegistryError","httpStatus":null,"severity":"error","filePath":"agent/src/factors/registry.py","lineNumber":383,"sourceCode":"        if spec is None or spec.loader is None:\n            raise RegistryError(f\"{alpha.id}: could not build import spec for {py_file}\")\n        module = importlib.util.module_from_spec(spec)\n        sys.modules[alpha.module_path] = module\n        try:\n            spec.loader.exec_module(module)\n        except Exception:\n            sys.modules.pop(alpha.module_path, None)\n            raise\n        return module\n\n    @staticmethod\n    def _validate_output(\n        alpha_id: str,\n        result: Any,\n        panel: dict[str, pd.DataFrame],\n    ) -> pd.DataFrame:\n        if not isinstance(result, pd.DataFrame):\n            raise RegistryError(\n                f\"{alpha_id}: compute() returned {type(result).__name__}, expected DataFrame\"\n            )\n        ref = panel.get(\"close\")\n        if ref is not None and result.shape != ref.shape:\n            raise RegistryError(\n                f\"{alpha_id}: output shape {result.shape} != close shape {ref.shape}\"\n            )\n        arr = result.to_numpy(dtype=np.float64, na_value=np.nan)\n        if np.isinf(arr).any():\n            raise RegistryError(f\"{alpha_id}: output contains +/- inf\")\n        nan_ratio = float(np.isnan(arr).mean()) if arr.size > 0 else 1.0\n        if nan_ratio > 0.95:\n            raise RegistryError(f\"{alpha_id}: output >95% NaN (nan_ratio={nan_ratio:.3f})\")\n        return result\n\n    def export_manifest(self) -> dict[str, Any]:\n        \"\"\"Return a JSON-serialisable snapshot for wiki rendering.\"\"\"\n        from datetime import datetime, timezone","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/factors/registry.py#L365-L401","documentation":"After compute() returns, _validate_output requires a pandas DataFrame. Any other type (Series, ndarray, scalar, None) fails with this RegistryError naming the actual type returned.","triggerScenarios":"An alpha whose compute returns df.iloc[:,0] (a Series), a numpy array, a dict of DataFrames, or None instead of a wide DataFrame.","commonSituations":"Factors written against a Series-based convention; returns squeezed accidentally; early-return None on empty input.","solutions":["Return a 2D wide DataFrame (dates x symbols) from compute()","Convert: `return s.to_frame()` for Series, `return pd.DataFrame(arr, index=close.index, columns=close.columns)` for arrays","Follow the zoo template's return convention"],"exampleFix":"# before\ndef compute(panel):\n    return (panel['close'] - panel['open']).mean(axis=1)  # Series\n# after\ndef compute(panel):\n    return (panel['close'] - panel['open'])  # DataFrame","handlingStrategy":"type-guard","validationCode":"res = mod.compute(panel)  # in dev\nassert isinstance(res, pd.DataFrame), type(res)","typeGuard":"def is_wide_frame(x) -> bool:\n    return isinstance(x, pd.DataFrame) and x.ndim == 2","tryCatchPattern":"try:\n    out = registry.compute(aid, panel)\nexcept RegistryError as e:\n    if 'expected DataFrame' in str(e): skip(aid)\n    else: raise","preventionTips":["Follow the zoo return contract: always return a DataFrame","Unit-test each factor's return type"],"tags":["type-validation","pandas","contract"],"backgroundTag":"unexpected-return-type","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}