{"record":{"id":"1765125e8e2ec62e","repo":"HKUDS/Vibe-Trading","slug":"inverted-page-range-part-r","errorCode":null,"errorMessage":"inverted page range: {part!r}","messagePattern":"inverted page range: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/doc_reader_tool.py","lineNumber":124,"sourceCode":"    \"\"\"Parse '1-10' / '5' / '1,3,5-8' into zero-based indices.\"\"\"\n    # Word/LLM paste often uses en/em/minus dashes; treat as ASCII hyphen.\n    pages_str = (\n        pages_str.replace(\"\\u2013\", \"-\")\n        .replace(\"\\u2014\", \"-\")\n        .replace(\"\\u2212\", \"-\")\n    )\n    out: list[int] = []\n    for part in pages_str.split(\",\"):\n        part = part.strip()\n        if not part:\n            continue\n        if \"-\" in part:\n            start, end = part.split(\"-\", 1)\n            start_1 = int(start.strip())\n            end_1 = int(end.strip())\n            # Mirror alpha_bench_tool._parse_period: reject inverted ranges.\n            if start_1 > end_1:\n                raise ValueError(f\"inverted page range: {part!r}\")\n            s = max(start_1 - 1, 0)\n            e = min(end_1, total)\n            out.extend(range(s, e))\n        elif part.isdigit():\n            out.append(int(part) - 1)\n    return sorted(set(out))\n\n\ndef _read_pdf(path: Path, pages: str, min_text_per_page: int = _MIN_TEXT_PER_PAGE) -> str:\n    \"\"\"Extract PDF text; OCR pages with too little text.\"\"\"\n    try:\n        import pypdfium2 as pdfium  # type: ignore\n    except ImportError:\n        return _err(\"pypdfium2 not installed; cannot read PDF\")\n\n    doc = pdfium.PdfDocument(str(path))\n    try:\n        total_pages = len(doc)","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/doc_reader_tool.py#L106-L142","documentation":"Raised when parsing a page-range token like 'start-end' where start > end, e.g. '5-2'. The parser mirrors alpha_bench_tool._parse_period and refuses inverted ranges rather than silently returning an empty page set.","triggerScenarios":"Calling the doc reader with pages='5-2', pages='10-3'; also triggers with dash forms including em/en dashes that resolve to inverted numbers, e.g. '5–2'.","commonSituations":"User typos in a pages= argument; LLM agents transposing numbers; swapped start/end variables when building the range programmatically.","solutions":["Swap the endpoints so the smaller page comes first (e.g. '2-5')","If generating ranges in code, assert start <= end before formatting the string"],"exampleFix":"# before\nread(path, pages=\"5-2\")\n# after\nread(path, pages=\"2-5\")","handlingStrategy":"validation","validationCode":"import re\n\ndef valid_pages(spec: str) -> bool:\n    for part in spec.split(\",\"):\n        part = part.strip().replace(\"\\u2013\", \"-\").replace(\"\\u2014\", \"-\")\n        if \"-\" in part:\n            a, b = part.split(\"-\", 1)\n            if not (a.strip().isdigit() and b.strip().isdigit()):\n                return False\n            if int(a) > int(b):\n                return False\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    text = read(path, pages=spec)\nexcept ValueError as exc:\n    if \"inverted page range\" in str(exc):\n        text = read(path)  # fall back to full document\n    else:\n        raise","preventionTips":["Normalize em/en dashes to '-' before passing page specs","If building ranges programmatically, assert lo <= hi","Validate the spec with a regex like ^\\d+([\\u2013\\u2014-]\\d+)?(,...)*$ first"],"tags":["validation","pdf","page-range","python"],"backgroundTag":"inverted-range-argument","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}