HKUDS/Vibe-Trading · error · ValueError

returns must be 1-D, got shape {ret_values.shape}

Error message

returns must be 1-D, got shape {ret_values.shape}

What it means

After index checks, _align converts returns to a 1-D float array; if it has more than one dimension (a DataFrame, a 2-D ndarray, or a (n,1) column vector) it raises ValueError with the offending shape. Backtesting logic compares each return scalar against one VaR scalar, so 2-D input is ambiguous.

Source

Thrown at agent/src/quantlib/var_backtest.py:274

    """
    ret_index = returns.index if isinstance(returns, pd.Series) else None
    var_index = var.index if isinstance(var, pd.Series) else None

    if ret_index is not None and var_index is not None:
        if not ret_index.equals(var_index):
            only_ret = ret_index.difference(var_index)
            only_var = var_index.difference(ret_index)
            raise ValueError(
                "returns and var must cover exactly the same labels; "
                f"{len(only_ret)} label(s) only in returns and "
                f"{len(only_var)} only in var. Align them explicitly -- a "
                "partial join silently compares each day against another day's "
                "forecast."
            )

    ret_values = np.asarray(returns, dtype=float)
    if ret_values.ndim > 1:
        raise ValueError(f"returns must be 1-D, got shape {ret_values.shape}")
    ret_values = ret_values.ravel()

    var_values = np.asarray(var, dtype=float)
    if var_values.ndim == 0:
        var_values = np.full(ret_values.shape, float(var_values))
    else:
        if var_values.ndim > 1:
            raise ValueError(f"var must be 1-D or scalar, got shape {var_values.shape}")
        var_values = var_values.ravel()

    if ret_values.size != var_values.size:
        raise ValueError(
            f"returns and var must be the same length, got {ret_values.size} "
            f"and {var_values.size}"
        )
    if ret_values.size == 0:
        raise ValueError("returns is empty")

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Select a single column/Series: returns['AAPL'] or returns[:, 0].
  2. Reshape 2-D arrays: returns.reshape(-1) or np.ravel(returns).
  3. If backtesting a portfolio, aggregate to portfolio returns first, then call var_backtest per series.

Example fix

# before
var_backtest(returns_df, var_series)  # shape (500, 3)
# after
var_backtest(returns_df['portfolio'], var_series)  # 1-D
Defensive patterns

Strategy: type-guard

Validate before calling

import numpy as np
assert np.asarray(returns, dtype=float).ndim <= 1

Type guard

def is_1d(x) -> bool:
    import numpy as np
    return np.asarray(x).ndim <= 1

Try / catch

except ValueError as e:
    if 'must be 1-D' in str(e) and 'returns' in str(e): returns = np.ravel(returns)

Prevention

When it happens

Trigger: Passing a pandas DataFrame of returns instead of a Series, or an ndarray with shape (n,1) from a model output; passing multiple asset return columns at once.

Common situations: Portfolio backtests where returns is a wide DataFrame; sklearn/statsmodels wrappers returning 2-D arrays; selecting a column but keeping shape via [[...]] indexing.

Related errors


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