{"record":{"id":"297140e37e48ed72","repo":"MemPalace/mempalace","slug":"chunk-overlap-chunk-overlap-must-be-at-most-ch","errorCode":null,"errorMessage":"chunk_overlap ({chunk_overlap}) must be at most chunk_size // 2 ({chunk_size // 2}); a larger overlap can loop forever on short-line content (#2056)","messagePattern":"chunk_overlap \\((.+?)\\) must be at most chunk_size // 2 \\((.+?)\\); a larger overlap can loop forever on short-line content \\(#2056\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mempalace/miner.py","lineNumber":676,"sourceCode":"    # enforces these and falls back to defaults on bad config.json\n    # values, but ``chunk_text`` is a public function — direct callers\n    # (tests, library users, future caller paths) might still pass\n    # values that would loop forever. Fail fast and loud rather than\n    # hang. See review feedback on #1024.\n    if not isinstance(chunk_size, int) or chunk_size <= 0:\n        raise ValueError(f\"chunk_size must be a positive int, got {chunk_size!r}\")\n    if not isinstance(chunk_overlap, int) or chunk_overlap < 0:\n        raise ValueError(f\"chunk_overlap must be a non-negative int, got {chunk_overlap!r}\")\n    if chunk_overlap > chunk_size // 2:\n        # The windowing loop pulls ``end`` back to a boundary only when that\n        # boundary is past ``start + chunk_size // 2`` (the rfind guards below),\n        # so a pulled chunk always spans more than ``chunk_size // 2`` chars.\n        # ``start = end - chunk_overlap`` therefore advances only while\n        # ``chunk_overlap <= chunk_size // 2``; a larger overlap makes ``start``\n        # stall or move backward and the loop spins forever on short-line\n        # content (#2056). The largest safe value is ``chunk_size // 2`` (half,\n        # rounded down for odd sizes), which still advances and stays allowed.\n        raise ValueError(\n            f\"chunk_overlap ({chunk_overlap}) must be at most chunk_size // 2 \"\n            f\"({chunk_size // 2}); a larger overlap can loop forever on \"\n            f\"short-line content (#2056)\"\n        )\n    if not isinstance(min_chunk_size, int) or min_chunk_size < 0:\n        raise ValueError(f\"min_chunk_size must be a non-negative int, got {min_chunk_size!r}\")\n\n    # Clean up\n    content = content.strip()\n    if not content:\n        return []\n\n    chunks = []\n    start = 0\n    chunk_index = 0\n\n    # Running newline tallies for the 1-indexed (line_start, line_end)\n    # locators emitted below. These replace the previous per-chunk","sourceCodeStart":658,"sourceCodeEnd":694,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/miner.py#L658-L694","documentation":"Error \"chunk_overlap ({chunk_overlap}) must be at most chunk_size // 2 ({chunk_size // 2}); a larger overlap can loop forever on short-line content (#2056)\" thrown in MemPalace/mempalace.","triggerScenarios":"Thrown at mempalace/miner.py:676 when the library encounters an invalid state.","commonSituations":"Overlap larger than half the chunk size can loop forever on short-line content.","solutions":["Reduce chunk_overlap to at most half of chunk_size"],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}