{"record":{"id":"1c0d703763a47f31","repo":"HKUDS/Vibe-Trading","slug":"period-period-r-must-be-yyyy-yyyy-or-yyyy-mm-dd","errorCode":null,"errorMessage":"period {period!r} must be YYYY-YYYY or YYYY-MM-DD/YYYY-MM-DD","messagePattern":"period (.+?) must be YYYY-YYYY or YYYY-MM-DD/YYYY-MM-DD","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/alpha_bench_tool.py","lineNumber":92,"sourceCode":"    \"csi300\": \"equity_cn\",\n    \"sp500\": \"equity_us\",\n    \"btc-usdt\": \"crypto\",\n}\n\n\ndef _parse_period(period: str) -> tuple[str, str]:\n    \"\"\"Return (start_date, end_date) as YYYY-MM-DD strings.\"\"\"\n    if not isinstance(period, str):\n        raise ValueError(f\"period must be string, got {type(period).__name__}\")\n    m = _PERIOD_DATE.match(period)\n    if m:\n        start, end = m.group(1), m.group(2)\n    else:\n        m = _PERIOD_YEAR.match(period)\n        if m:\n            start, end = f\"{m.group(1)}-01-01\", f\"{m.group(2)}-12-31\"\n        else:\n            raise ValueError(\n                f\"period {period!r} must be YYYY-YYYY or YYYY-MM-DD/YYYY-MM-DD\"\n            )\n    # Match backtest loaders.validate_date_range: reject inverted ranges.\n    if pd.Timestamp(start) > pd.Timestamp(end):\n        raise ValueError(f\"start_date ({start}) > end_date ({end})\")\n    return start, end\n\n\ndef _load_universe_panel(\n    universe: str, period: str, *, use_cache: bool = True\n) -> dict[str, pd.DataFrame]:\n    \"\"\"Load OHLCV(+amount, +vwap) wide panel for the requested universe.\n\n    Returns a dict keyed by panel column (open/high/low/close/volume/amount/vwap)\n    where each value is a wide ``pd.DataFrame`` indexed by date (DatetimeIndex)\n    with one column per instrument.\n\n    Args:","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/alpha_bench_tool.py#L74-L110","documentation":"_parse_period only accepts two formats: 'YYYY-YYYY' (year range, expanded to Jan 1 – Dec 31) or 'YYYY-MM-DD/YYYY-MM-DD'. Anything else that is a string but matches neither regex raises this.","triggerScenarios":"Calling alpha_bench-family tools with period='2020', '2020/2021', '2020-01-01 - 2023-12-31', 'last 3 years', or other free-form strings.","commonSituations":"LLM tool calls with natural-language periods; users copying formats from other tools (dash instead of slash separators); locale-formatted dates.","solutions":["Use 'YYYY-YYYY' for whole years (e.g. '2020-2023')","Use 'YYYY-MM-DD/YYYY-MM-DD' with a slash separator for exact ranges","Add a pre-call regex check mirroring _PERIOD_YEAR/_PERIOD_DATE to give a better message"],"exampleFix":"// before\nalpha_bench(universe='csi300', period='2020 to 2023')\n// after\nalpha_bench(universe='csi300', period='2020-2023')","handlingStrategy":"validation","validationCode":"import re\nassert re.fullmatch(r'\\d{4}-\\d{4}|\\d{4}-\\d{2}-\\d{2}/\\d{4}-\\d{2}-\\d{2}', period), 'bad period format'","typeGuard":"import re\ndef is_valid_period(p: str) -> bool:\n    return bool(re.fullmatch(r'\\d{4}(-\\d{2}-\\d{2})?/\\d{4}(-\\d{2}-\\d{2})?|\\d{4}-\\d{4}', p))","tryCatchPattern":"try:\n    _parse_period(period)\nexcept ValueError as e:\n    raise ToolInputError(f'fix period format: {e}') from e","preventionTips":["Offer callers a (start, end) date API and build the string yourself","Document the two accepted formats next to the parameter"],"tags":["date-format","validation","alpha-bench"],"backgroundTag":"invalid-date-range-format","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}