HKUDS/Vibe-Trading · error · RegistryError

{alpha_id}: compute() returned {type(result).__name__}, expe

Error message

{alpha_id}: compute() returned {type(result).__name__}, expected DataFrame

What it means

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.

Source

Thrown at agent/src/factors/registry.py:383

        if spec is None or spec.loader is None:
            raise RegistryError(f"{alpha.id}: could not build import spec for {py_file}")
        module = importlib.util.module_from_spec(spec)
        sys.modules[alpha.module_path] = module
        try:
            spec.loader.exec_module(module)
        except Exception:
            sys.modules.pop(alpha.module_path, None)
            raise
        return module

    @staticmethod
    def _validate_output(
        alpha_id: str,
        result: Any,
        panel: dict[str, pd.DataFrame],
    ) -> pd.DataFrame:
        if not isinstance(result, pd.DataFrame):
            raise RegistryError(
                f"{alpha_id}: compute() returned {type(result).__name__}, expected DataFrame"
            )
        ref = panel.get("close")
        if ref is not None and result.shape != ref.shape:
            raise RegistryError(
                f"{alpha_id}: output shape {result.shape} != close shape {ref.shape}"
            )
        arr = result.to_numpy(dtype=np.float64, na_value=np.nan)
        if np.isinf(arr).any():
            raise RegistryError(f"{alpha_id}: output contains +/- inf")
        nan_ratio = float(np.isnan(arr).mean()) if arr.size > 0 else 1.0
        if nan_ratio > 0.95:
            raise RegistryError(f"{alpha_id}: output >95% NaN (nan_ratio={nan_ratio:.3f})")
        return result

    def export_manifest(self) -> dict[str, Any]:
        """Return a JSON-serialisable snapshot for wiki rendering."""
        from datetime import datetime, timezone

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Return a 2D wide DataFrame (dates x symbols) from compute()
  2. Convert: `return s.to_frame()` for Series, `return pd.DataFrame(arr, index=close.index, columns=close.columns)` for arrays
  3. Follow the zoo template's return convention

Example fix

# before
def compute(panel):
    return (panel['close'] - panel['open']).mean(axis=1)  # Series
# after
def compute(panel):
    return (panel['close'] - panel['open'])  # DataFrame
Defensive patterns

Strategy: type-guard

Validate before calling

res = mod.compute(panel)  # in dev
assert isinstance(res, pd.DataFrame), type(res)

Type guard

def is_wide_frame(x) -> bool:
    return isinstance(x, pd.DataFrame) and x.ndim == 2

Try / catch

try:
    out = registry.compute(aid, panel)
except RegistryError as e:
    if 'expected DataFrame' in str(e): skip(aid)
    else: raise

Prevention

When it happens

Trigger: An alpha whose compute returns df.iloc[:,0] (a Series), a numpy array, a dict of DataFrames, or None instead of a wide DataFrame.

Common situations: Factors written against a Series-based convention; returns squeezed accidentally; early-return None on empty input.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/9b354e8ccf078079. Report an issue: GitHub.