{"record":{"id":"7fcc47e8e17b0fe5","repo":"HKUDS/Vibe-Trading","slug":"ts-min-window-must-be-1-got-n","errorCode":null,"errorMessage":"ts_min window must be >= 1, got {n}","messagePattern":"ts_min window must be >= 1, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/factors/base.py","lineNumber":203,"sourceCode":"\ndef ts_std(df: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Rolling sample std (ddof=1) per column, warmup → NaN.\"\"\"\n    if n < 2:\n        raise ValueError(f\"ts_std window must be >= 2, got {n}\")\n    return df.rolling(window=n, min_periods=n).std(ddof=1)\n\n\ndef ts_max(df: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Rolling max per column, warmup → NaN.\"\"\"\n    if n < 1:\n        raise ValueError(f\"ts_max window must be >= 1, got {n}\")\n    return df.rolling(window=n, min_periods=n).max()\n\n\ndef ts_min(df: pd.DataFrame, n: int) -> pd.DataFrame:\n    \"\"\"Rolling min per column, warmup → NaN.\"\"\"\n    if n < 1:\n        raise ValueError(f\"ts_min window must be >= 1, got {n}\")\n    return df.rolling(window=n, min_periods=n).min()\n\n\ndef _argmax_last(arr: np.ndarray) -> float:\n    if np.isnan(arr).all():\n        return np.nan\n    arr_filled = np.where(np.isnan(arr), -np.inf, arr)\n    return float(np.argmax(arr_filled))\n\n\ndef _argmin_last(arr: np.ndarray) -> float:\n    if np.isnan(arr).all():\n        return np.nan\n    arr_filled = np.where(np.isnan(arr), np.inf, arr)\n    return float(np.argmin(arr_filled))\n\n\ndef ts_argmax(df: pd.DataFrame, n: int) -> pd.DataFrame:","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/factors/base.py#L185-L221","documentation":"ts_min computes a rolling minimum per column with NaN warmup. Like ts_max it requires window n >= 1 since pandas rolling cannot accept zero/negative windows; the guard raises ValueError before pandas does.","triggerScenarios":"Calling ts_min(df, 0) or ts_min(df, -1), or a parameterized factor spec with a bad window value.","commonSituations":"YAML/JSON factor configs with window: 0, dynamically computed windows on tiny datasets, or copy-paste from a spec using a different convention (0-based windows).","solutions":["Use a window >= 1","Validate factor spec windows at load time","Clamp computed windows with max(1, n)"],"exampleFix":"// before\nts_min(df, n)\n// after\nif n < 1: raise ValueError('window must be >= 1')\nts_min(df, n)","handlingStrategy":"validation","validationCode":"if not isinstance(n, int) or n < 1: raise ValueError(f'window must be int >= 1, got {n!r}')","typeGuard":"def is_valid_window(n: object) -> bool:\n    return isinstance(n, int) and not isinstance(n, bool) and n >= 1","tryCatchPattern":null,"preventionTips":["Validate window specs once in a config schema","Add unit tests for boundary windows (0, 1, negative)"],"tags":["rolling-window","validation","pandas"],"backgroundTag":"invalid-window-size","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}