{"record":{"id":"c15c2027a5d9abe2","repo":"Panniantong/Agent-Reach","slug":"chunk-segment-duration-must-be-positive","errorCode":null,"errorMessage":"chunk segment duration must be positive","messagePattern":"chunk segment duration must be positive","errorType":"exception","errorClass":"TranscribeError","httpStatus":null,"severity":"error","filePath":"agent_reach/transcribe.py","lineNumber":314,"sourceCode":"            \"-t\",\n            str(MAX_AUDIO_SECONDS),\n            \"-vn\",\n            \"-ac\",\n            \"1\",\n            \"-ar\",\n            \"16000\",\n            \"-b:a\",\n            \"32k\",\n            str(dst),\n        ]\n    )\n    return dst\n\n\ndef chunk_audio(src: Path, out_dir: Path, segment_seconds: int = CHUNK_SECONDS) -> List[Path]:\n    \"\"\"Split src into segments. Re-encodes each segment so cuts align to keyframes.\"\"\"\n    if segment_seconds <= 0:\n        raise TranscribeError(\"chunk segment duration must be positive\")\n    possible_chunks = (\n        MAX_AUDIO_SECONDS + segment_seconds - 1\n    ) // segment_seconds\n    if possible_chunks > MAX_CHUNKS:\n        raise TranscribeError(\n            f\"chunk generation safety limit is {MAX_CHUNKS}; \"\n            f\"segment duration {segment_seconds}s could create \"\n            f\"{possible_chunks} chunks\"\n        )\n    _require(\"ffmpeg\")\n    pattern = out_dir / \"chunk_%03d.m4a\"\n    _run(\n        [\n            \"ffmpeg\",\n            \"-loglevel\",\n            \"error\",\n            \"-y\",\n            \"-i\",","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/Panniantong/Agent-Reach/blob/93ae1d18c37b707dec053c7c4f9d91cd8ef8943d/agent_reach/transcribe.py#L296-L332","documentation":"Raised by chunk_audio (transcribe.py:311-314) when the caller passes segment_seconds <= 0. The value feeds ffmpeg's -segment_time, which requires a positive duration; the Python-side check gives a clear error before spawning ffmpeg with a nonsensical argument.","triggerScenarios":"Calling chunk_audio(src, out_dir, segment_seconds=0) or a negative value, usually because a computed segment size (e.g. size // duration) divided down to zero, or a config default of 0 was never overridden. The public transcribe() never triggers this — it uses the CHUNK_SECONDS=600 default.","commonSituations":"Custom callers tuning chunk length from user config where a missing setting defaults to 0; integer division of small sizes by large counts producing 0; test fixtures passing 0 to mean 'default'.","solutions":["Pass a positive segment length, or omit it to use the 600s default: chunk_audio(src, out_dir)","If computing segment_seconds dynamically, clamp: max(1, computed)","Validate config before the call: if cfg.segment_seconds <= 0: use CHUNK_SECONDS"],"exampleFix":"# before\nsegment = total_bytes // expected_chunks  # -> 0\nchunk_audio(src, out_dir, segment_seconds=segment)\n\n# after\nsegment = max(1, total_bytes // expected_chunks) if expected_chunks else CHUNK_SECONDS\nchunk_audio(src, out_dir, segment_seconds=segment)","handlingStrategy":"validation","validationCode":"def valid_segment_seconds(value: int) -> bool:\n    return isinstance(value, int) and value > 0","typeGuard":null,"tryCatchPattern":"from agent_reach.transcribe import TranscribeError\ntry:\n    chunk_audio(src, out_dir, segment_seconds=seg)\nexcept TranscribeError as e:\n    if \"must be positive\" in str(e):\n        return chunk_audio(src, out_dir)  # fall back to the 600s default\n    raise","preventionTips":["Clamp computed segment values: max(1, computed)","Treat 0 in config as 'unset' and substitute CHUNK_SECONDS","Prefer omitting segment_seconds unless you truly need custom chunking"],"tags":["validation","ffmpeg","chunking","transcription"],"backgroundTag":null,"analyzedSha":"93ae1d18c37b707dec053c7c4f9d91cd8ef8943d","analyzedAt":"2026-08-14T22:54:06.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}