{"record":{"id":"551d49c14dce851b","repo":"Panniantong/Agent-Reach","slug":"ffprobe-failed-while-reading-audio-duration-deta","errorCode":null,"errorMessage":"ffprobe failed while reading audio duration: {detail}","messagePattern":"ffprobe failed while reading audio duration: (.+?)","errorType":"exception","errorClass":"TranscribeError","httpStatus":null,"severity":"error","filePath":"agent_reach/transcribe.py","lineNumber":126,"sourceCode":"            cmd,\n            capture_output=True,\n            encoding=\"utf-8\",\n            errors=\"replace\",\n            timeout=FFPROBE_TIMEOUT_SECONDS,\n        )\n    except subprocess.TimeoutExpired:\n        raise TranscribeError(\n            \"ffprobe timed out while reading audio duration \"\n            f\"after {FFPROBE_TIMEOUT_SECONDS}s\"\n        ) from None\n    except OSError as exc:\n        raise TranscribeError(\n            f\"ffprobe could not read audio duration: {exc}\"\n        ) from exc\n\n    if proc.returncode != 0:\n        detail = proc.stderr.strip()[:300] or \"unknown ffprobe error\"\n        raise TranscribeError(\n            f\"ffprobe failed while reading audio duration: {detail}\"\n        )\n\n    raw_duration = proc.stdout.strip()\n    try:\n        duration = float(raw_duration)\n    except (TypeError, ValueError):\n        raise TranscribeError(\n            \"ffprobe could not parse a valid audio duration\"\n        ) from None\n    if not math.isfinite(duration) or duration <= 0:\n        raise TranscribeError(\n            \"ffprobe could not parse a valid positive audio duration\"\n        )\n    return duration\n\n\ndef _require_duration_within_budget(path: Path) -> float:","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/Panniantong/Agent-Reach/blob/93ae1d18c37b707dec053c7c4f9d91cd8ef8943d/agent_reach/transcribe.py#L108-L144","documentation":"Raised by _probe_audio_duration() in agent_reach/transcribe.py when ffprobe exits non-zero while reading format duration. The first 300 characters of ffprobe's stderr become the message detail (or 'unknown ffprobe error' if stderr is empty), so the exact container/codec problem is surfaced — e.g. 'Invalid data found when processing input'.","triggerScenarios":"Passing a corrupt, truncated, or non-media file (renamed .mp3 with random bytes); unsupported containers; zero-byte files.","commonSituations":"Interrupted downloads; files that are actually HTML error pages saved with a media extension; DRM-protected media ffprobe cannot parse.","solutions":["Read the stderr detail in the message — it names the real problem","Verify the file plays locally or re-obtain it from the source","Repair the container: ffmpeg -errdetect ignore_err -i in.file -c copy fixed.file"],"exampleFix":"# before\ntranscribe_audio(Path('video.mp4'))  # really an HTML error page\n\n# after: validate the download first\nassert data[:4] != b'<!DO', 'download failed'\ntranscribe_audio(Path('video.mp4'))","handlingStrategy":"validation","validationCode":"import subprocess\nr = subprocess.run(['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-i', str(path)], capture_output=True, text=True)\nif r.returncode != 0:\n    raise ValueError(f'media unreadable by ffprobe: {r.stderr[:300]}')","typeGuard":"def probeable_media(path) -> bool:\n    r = subprocess.run(['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-i', str(path)], capture_output=True)\n    return r.returncode == 0","tryCatchPattern":"from agent_reach.transcribe import TranscribeError\ntry:\n    transcribe_audio(path)\nexcept TranscribeError as e:\n    if 'ffprobe failed' in str(e):\n        repaired = remux(path)  # ffmpeg -c copy fallback\n        transcribe_audio(repaired)\n    else:\n        raise","preventionTips":["Validate downloads (content-type, magic bytes) before transcribing","Read the embedded stderr detail — it identifies the codec/container fault","Re-mux suspicious files before retry"],"tags":["ffprobe","corrupt-file","media","validation"],"backgroundTag":null,"analyzedSha":"93ae1d18c37b707dec053c7c4f9d91cd8ef8943d","analyzedAt":"2026-08-14T22:54:06.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}