{"record":{"id":"f084c2c55850ac43","repo":"HKUDS/Vibe-Trading","slug":"quarter-value-r-is-not-recognizable-use-2026q1","errorCode":null,"errorMessage":"quarter {value!r} is not recognizable; use '2026Q1' or a quarter-end date '2026-03-31'","messagePattern":"quarter (.+?) is not recognizable; use '2026Q1' or a quarter-end date '2026-03-31'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/institutional_holdings_tool.py","lineNumber":355,"sourceCode":"\n    Args:\n        value: The raw ``quarter`` argument.\n\n    Returns:\n        The quarter-end date as ``YYYY-MM-DD``.\n\n    Raises:\n        ValueError: When the text is not a recognizable quarter, the year is\n            outside ``1993..current+1``, or the date is not a quarter end.\n    \"\"\"\n    text = str(value).strip().upper().replace(\" \", \"\")\n    match = re.fullmatch(r\"(\\d{4})-?Q([1-4])\", text)\n    if match:\n        year, quarter = int(match.group(1)), int(match.group(2))\n    else:\n        match = re.fullmatch(r\"(\\d{4})-(\\d{1,2})-(\\d{1,2})\", text)\n        if not match:\n            raise ValueError(\n                f\"quarter {value!r} is not recognizable; use '2026Q1' or a quarter-end date '2026-03-31'\"\n            )\n        year, month, day = (int(g) for g in match.groups())\n        quarter = next((q for q, md in _QUARTER_ENDS.items() if md == (month, day)), None)\n        if quarter is None:\n            raise ValueError(\n                f\"quarter {value!r} is not a calendar quarter end; use 03-31, 06-30, 09-30 or 12-31\"\n            )\n    if not _MIN_QUARTER_YEAR <= year <= date.today().year + 1:\n        raise ValueError(f\"quarter year {year} is outside {_MIN_QUARTER_YEAR}..{date.today().year + 1}\")\n    month, day = _QUARTER_ENDS[quarter]\n    return f\"{year:04d}-{month:02d}-{day:02d}\"\n\n\ndef _quarter_label(period_end: Optional[str]) -> Optional[str]:\n    \"\"\"Render a ``YYYY-MM-DD`` quarter end as ``YYYYQn``, or ``None`` if unusable.\"\"\"\n    if not period_end or len(str(period_end)) < 7:\n        return None","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/institutional_holdings_tool.py#L337-L373","documentation":"_parse_quarter accepts 'YYYYQn' (with optional hyphen) or 'YYYY-MM-DD' strings; anything not matching either regex raises this with usage guidance. It normalizes quarter inputs for the institutional holdings tool.","triggerScenarios":"Passing quarter='Q1 2026', '2026/q1', 'Mar 2026', '2026-3-31' with non-2-digit forms is OK for digits, but '2026Q5', 'first quarter', or '20260331' fail the fullmatch.","commonSituations":"LLM or user supplying natural-language quarters, fiscal quarter labels ('FY26Q1' with prefix), or concatenated date formats.","solutions":["Format as '2026Q1' or '2026-03-31' before calling","Map fiscal labels to calendar quarters upstream","Catch ValueError and re-prompt with the accepted formats"],"exampleFix":"# before\nexecute(quarter=\"Q1 2026\")\n# after\nexecute(quarter=\"2026Q1\")","handlingStrategy":"validation","validationCode":"import re\nm = re.fullmatch(r\"(\\d{4})-?Q([1-4])\", q) or re.fullmatch(r\"(\\d{4})-(\\d{1,2})-(\\d{1,2})\", q)\nassert m, f\"bad quarter {q!r}; use '2026Q1' or '2026-03-31'\"","typeGuard":"def is_parseable_quarter(q: str) -> bool:\n    import re\n    return bool(re.fullmatch(r\"\\d{4}-?Q[1-4]\", q) or re.fullmatch(r\"\\d{4}-\\d{1,2}-\\d{1,2}\", q))","tryCatchPattern":"try:\n    qn = _parse_quarter(user_q)\nexcept ValueError as e:\n    if \"not recognizable\" in str(e):\n        qn = normalize_quarter_string(user_q)  # map 'Q1 2026' -> '2026Q1'\n    else:\n        raise","preventionTips":["Canonicalize to YYYYQn in the UI/LLM prompt","Reject concatenated or localized date formats early"],"tags":["python","date-parsing","validation"],"backgroundTag":"invalid-date-format","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}