tonhowtf/omniget · error

Missing 'format' field

Error message

Missing 'format' field

What it means

After parsing ffprobe's JSON, probe() requires the top-level "format" object which ffprobe emits with -show_format. If the JSON lacks it, the code fails with this error. It means ffprobe produced valid JSON but without the expected format section.

Solutions

  1. Confirm the ffprobe arguments include -show_format (and -show_streams if needed).
  2. Check the input file is a real media file: `ffprobe -show_format <file>` and look for the format section.
  3. Guard against probing empty/zero-byte or special files before calling get_duration_us.
  4. Log the parsed JSON on failure to see which sections ffprobe actually returned.

Example fix

// before
let format = json
    .get("format")
    .ok_or_else(|| anyhow!("Missing 'format' field"))?;
// after
let format = json.get("format").ok_or_else(|| {
    anyhow!(
        "Missing 'format' field in ffprobe output: {}",
        String::from_utf8_lossy(&output.stdout)
    )
})?;
Defensive patterns

Strategy: validation

Validate before calling

let out = std::process::Command::new("ffprobe")
    .args(["-v", "quiet", "-print_format", "json", "-show_format", path])
    .output()?;
let json: serde_json::Value = serde_json::from_slice(&out.stdout)?;
if json.get("format").is_none() {
    return Err("input has no container format; not a regular media file".into());
}

Type guard

fn has_format_section(v: &serde_json::Value) -> bool {
    v.get("format").map(|f| f.is_object()).unwrap_or(false)
}

Try / catch

match probe(path).await {
    Err(e) if e.to_string() == "Missing 'format' field" => {
        // treat as unsupported/invalid input file, skip metadata step
        skip_duration(path);
    }
    other => other?,
}

Prevention

When it happens

Trigger: get_duration_us or convert on a file where ffprobe succeeded but omitted -show_format data — e.g. ffprobe args dropped the flag, or probing a stream/device pseudo-file that has no container format.

Common situations: Probing special files (/dev/*, named pipes) that yield no container format; a modified ffprobe argument list that omits -show_format; probing an empty or zero-byte file that still parses as an empty JSON object.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/77d4869270417c8b. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/ffmpeg.rs:142

            &path.to_string_lossy(),
        ])
        .stdout(std::process::Stdio::piped())
        .stderr(std::process::Stdio::piped())
        .output()
        .await
        .map_err(|e| anyhow!("Failed to run ffprobe: {}", e))?;

    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        return Err(anyhow!("ffprobe failed: {}", stderr));
    }

    let json: serde_json::Value = serde_json::from_slice(&output.stdout)
        .map_err(|e| anyhow!("Failed to parse ffprobe JSON: {}", e))?;

    let format = json
        .get("format")
        .ok_or_else(|| anyhow!("Missing 'format' field"))?;

    let duration_seconds = format
        .get("duration")
        .and_then(|v| v.as_str())
        .and_then(|s| s.parse::<f64>().ok())
        .unwrap_or(0.0);

    let format_name = format
        .get("format_name")
        .and_then(|v| v.as_str())
        .unwrap_or("")
        .to_string();

    let format_long_name = format
        .get("format_long_name")
        .and_then(|v| v.as_str())
        .unwrap_or("")
        .to_string();

View on GitHub (pinned to 8600b91f42)