# Error Handling Mechanisms in helpers/render.py for Failed FFmpeg Commands

> Discover error handling for FFmpeg commands in browser-use/video-use. Learn how `helpers/render.py` manages critical failures and gracefully degrades non-critical operations.

- Repository: [Browser Use/video-use](https://github.com/browser-use/video-use)
- Tags: internals
- Published: 2026-06-30

---

**The [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) module in browser-use/video-use employs a tiered error-handling strategy that propagates critical FFmpeg failures via `subprocess.CalledProcessError` while gracefully degrading non-critical operations like HDR detection and loudness measurement to prevent pipeline collapse.**

The `browser-use/video-use` repository orchestrates complex video processing workflows through Python subprocess calls to FFmpeg and ffprobe. Within [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), error handling is not uniform; instead, the implementation distinguishes between critical rendering steps that must abort on failure and auxiliary probes that can safely fall back to default values.

## Critical Rendering Steps: Hard Failure with Exception Propagation

For essential operations—segment extraction, concatenation, final compositing, and loudness normalization—the code invokes `subprocess.run` with `check=True`. In [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), functions like the segment extractor use this pattern:

```python
subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)

```

When FFmpeg exits with a non-zero status, Python raises `subprocess.CalledProcessError`. This exception is intentionally uncaught within the helper functions, allowing it to propagate to the top-level `main()` function and terminate the script with a full traceback. This design ensures users receive immediate visibility into rendering blockers without silent data corruption.

The `run()` utility wrapper reinforces this behavior. Defined at lines 61-65 of [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), it prints the command for debugging and executes `subprocess.run(..., check=True)`, making it suitable for `build_final_composite()` when no overlays or subtitles require complex handling.

## Graceful Degradation for Non-Critical Probing

Not all failures warrant pipeline termination. For metadata probes that enhance quality but aren't essential to output generation, [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) implements defensive exception handling.

### HDR Detection Fallback

The `is_hdr_source()` function attempts to detect high dynamic range content via ffprobe. Rather than crashing when ffprobe fails, it wraps the call in a targeted exception handler at lines 121-131:

```python
try:
    out = subprocess.run([...ffprobe...], check=True, capture_output=True, text=True)
    return out.stdout.strip() in HDR_TRANSFERS
except subprocess.CalledProcessError:
    # Treat as non-HDR when ffprobe cannot read the file

    return False

```

If the command fails, the function returns `False`, causing the pipeline to proceed with standard dynamic range processing.

### Portrait Orientation Detection

Similarly, `is_portrait_source()` employs a broad `except Exception` block at lines 134-146 to catch any error during dimension probing. This guarantees that a failure to read video metadata never stalls rendering; the function simply returns `False`, treating the source as landscape.

## Soft Failure for Loudness Measurement

The `measure_loudness()` function (lines 97-104 and 119-128) takes a different approach. It executes FFmpeg **without** `check=True`, captures `stderr`, and attempts to parse JSON output. If the command fails or the JSON is malformed, the function returns `None` rather than raising an exception.

The caller, `apply_loudnorm_two_pass`, detects this `None` value and falls back to a one-pass loudness approximation:

```python
measurement = measure_loudness(video)
if measurement is None:
    # fall back to a quicker one-pass loudnorm

    apply_loudnorm_two_pass(..., preview=True)

```

This soft-failure pattern ensures that a broken loudness analysis never prevents video delivery, sacrificing optimal audio normalization for pipeline completion.

## Summary

- **Critical operations** in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) use `subprocess.run(check=True)` and allow `CalledProcessError` to propagate, aborting the script immediately when FFmpeg fails during extraction, concat, or compositing.
- **HDR detection** (`is_hdr_source`) catches `CalledProcessError` specifically and returns `False` to continue processing as non-HDR.
- **Portrait detection** (`is_portrait_source`) uses a generic `except Exception` to guarantee metadata failures don't block rendering.
- **Loudness measurement** (`measure_loudness`) returns `None` on failure, enabling callers to implement fallback audio processing strategies.
- The `run()` utility wrapper provides consistent command logging and hard-failure semantics for simple FFmpeg invocations.

## Frequently Asked Questions

### What happens when FFmpeg fails during video segment extraction?

The `extract_segment` function calls `subprocess.run` with `check=True`. If FFmpeg returns a non-zero exit code, Python raises `subprocess.CalledProcessError`, which propagates uncaught through [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) to terminate the script with a traceback containing the failed command.

### How does the pipeline handle ffprobe failures when detecting HDR content?

The `is_hdr_source()` function wraps its ffprobe call in a `try/except subprocess.CalledProcessError` block. If the probe fails—due to missing files or unsupported formats—it returns `False`, allowing the pipeline to continue treating the source as standard dynamic range rather than crashing.

### Why does loudness measurement return None instead of raising an exception?

`measure_loudness()` executes FFmpeg without `check=True` and returns `None` if the JSON output cannot be parsed or the command fails. This design lets `apply_loudnorm_two_pass` detect the failure and switch to a one-pass approximation, ensuring video rendering completes even when audio analysis fails.

### Where is the utility wrapper for FFmpeg commands defined?

The `run()` helper is defined at lines 61-65 in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py). It prints the command to stdout for debugging purposes and executes `subprocess.run` with `check=True`, standardizing error propagation for operations like `build_final_composite()` when no complex overlays are present.