{"record":{"id":"9d97534af74d06af","repo":"Panniantong/Agent-Reach","slug":"audio-produced-len-chunks-chunks-safety-limit","errorCode":null,"errorMessage":"audio produced {len(chunks)} chunks; safety limit is {MAX_CHUNKS} (~{max_minutes} minutes)","messagePattern":"audio produced (.+?) chunks; safety limit is (.+?) \\(~(.+?) minutes\\)","errorType":"exception","errorClass":"TranscribeError","httpStatus":null,"severity":"error","filePath":"agent_reach/transcribe.py","lineNumber":464,"sourceCode":"    work_dir.mkdir(parents=True, exist_ok=True)\n\n    src_path = Path(source)\n    if src_path.is_file():\n        audio = src_path\n    else:\n        audio = download_audio(source, work_dir)\n\n    _require_size_at_most(audio, MAX_SOURCE_BYTES, \"source\")\n    _require_duration_within_budget(audio)\n    compressed = compress_audio(audio, work_dir)\n    if compressed.stat().st_size <= SIZE_LIMIT_BYTES:\n        chunks = [compressed]\n    else:\n        chunks = chunk_audio(compressed, work_dir)\n\n    if len(chunks) > MAX_CHUNKS:\n        max_minutes = MAX_CHUNKS * CHUNK_SECONDS // 60\n        raise TranscribeError(\n            f\"audio produced {len(chunks)} chunks; safety limit is \"\n            f\"{MAX_CHUNKS} (~{max_minutes} minutes)\"\n        )\n    chunk_sizes = [\n        _require_size_at_most(chunk, SIZE_LIMIT_BYTES, f\"chunk {chunk.name}\")\n        for chunk in chunks\n    ]\n    total_chunk_bytes = sum(chunk_sizes)\n    if total_chunk_bytes > MAX_TOTAL_CHUNK_BYTES:\n        limit_mib = MAX_TOTAL_CHUNK_BYTES / (1024 * 1024)\n        raise TranscribeError(\n            f\"audio chunks total {total_chunk_bytes} bytes; \"\n            f\"safety limit is {limit_mib:g} MiB\"\n        )\n\n    pieces: List[str] = []\n    for chunk in chunks:\n        text = _transcribe_with_fallback(chunk, order, cfg)","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/Panniantong/Agent-Reach/blob/93ae1d18c37b707dec053c7c4f9d91cd8ef8943d/agent_reach/transcribe.py#L446-L482","documentation":"Raised after download/compress/chunk when the audio splits into more than MAX_CHUNKS (24) chunks of 10 minutes each, i.e. roughly 4 hours of audio. This is a cost and time safety valve so a single call cannot transcribe arbitrarily long media. It fires before any chunk is uploaded, so no API spend occurs.","triggerScenarios":"Calling transcribe() on a source longer than MAX_AUDIO_SECONDS (24 * 600s = 14400s = 4 hours), or on audio that compresses poorly (e.g. already-compressed formats) so chunk_audio must split the oversized compressed file into many size-based segments exceeding 24.","commonSituations":"Transcribing long podcasts, livestream VODs, multi-hour talks, or audiobooks; feeding a high-bitrate source file where compression cannot get under SIZE_LIMIT_BYTES per 10-minute segment.","solutions":["Trim or split the source externally (e.g. yt-dlp --download-sections or ffmpeg -ss/-t) and transcribe segments separately","Point transcribe() at a shorter portion of the media instead of the full item","If you own the deployment and accept the cost, raise MAX_CHUNKS in a fork — but prefer external splitting","For xiaoyuzhou episodes, use the bundled scripts/transcribe_xiaoyuzhou.sh flow which handles episode lengths itself"],"exampleFix":"# before\ntext = transcribe(\"https://www.youtube.com/watch?v=LONG_LIVESTREAM\")  # 25 chunks > 24\n\n# after — transcribe only the first 3 hours\n# yt-dlp --download-sections \"*0-3:00:00\" -o seg.mp4 \"<url>\"\ntext = transcribe(\"seg.mp4\")","handlingStrategy":"validation","validationCode":"from agent_reach.transcribe import MAX_AUDIO_SECONDS, MAX_CHUNKS, CHUNK_SECONDS\n\ndef duration_ok(seconds: float) -> bool:\n    return seconds <= MAX_AUDIO_SECONDS  # 24 * 600 = 14400s","typeGuard":null,"tryCatchPattern":"from agent_reach.transcribe import transcribe, TranscribeError\ntry:\n    text = transcribe(url)\nexcept TranscribeError as e:\n    if \"safety limit is\" in str(e) and \"chunks\" in str(e):\n        text = transcribe_in_parts(url, parts=4)  # your own splitter\n    else:\n        raise","preventionTips":["Probe duration with ffprobe before calling transcribe() and reject >4h sources","For long media, download once and transcribe time-sliced sections yourself","Treat this error as a hard cap — retrying unchanged will always fail"],"tags":["transcription","audio","limits","chunking","ffmpeg"],"backgroundTag":null,"analyzedSha":"93ae1d18c37b707dec053c7c4f9d91cd8ef8943d","analyzedAt":"2026-08-14T22:54:06.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}