{"record":{"id":"77d4869270417c8b","repo":"tonhowtf/omniget","slug":"missing-format-field","errorCode":null,"errorMessage":"Missing 'format' field","messagePattern":"Missing 'format' field","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/ffmpeg.rs","lineNumber":142,"sourceCode":"            &path.to_string_lossy(),\n        ])\n        .stdout(std::process::Stdio::piped())\n        .stderr(std::process::Stdio::piped())\n        .output()\n        .await\n        .map_err(|e| anyhow!(\"Failed to run ffprobe: {}\", e))?;\n\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        return Err(anyhow!(\"ffprobe failed: {}\", stderr));\n    }\n\n    let json: serde_json::Value = serde_json::from_slice(&output.stdout)\n        .map_err(|e| anyhow!(\"Failed to parse ffprobe JSON: {}\", e))?;\n\n    let format = json\n        .get(\"format\")\n        .ok_or_else(|| anyhow!(\"Missing 'format' field\"))?;\n\n    let duration_seconds = format\n        .get(\"duration\")\n        .and_then(|v| v.as_str())\n        .and_then(|s| s.parse::<f64>().ok())\n        .unwrap_or(0.0);\n\n    let format_name = format\n        .get(\"format_name\")\n        .and_then(|v| v.as_str())\n        .unwrap_or(\"\")\n        .to_string();\n\n    let format_long_name = format\n        .get(\"format_long_name\")\n        .and_then(|v| v.as_str())\n        .unwrap_or(\"\")\n        .to_string();","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/ffmpeg.rs#L124-L160","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the ffprobe arguments include -show_format (and -show_streams if needed).","Check the input file is a real media file: `ffprobe -show_format <file>` and look for the format section.","Guard against probing empty/zero-byte or special files before calling get_duration_us.","Log the parsed JSON on failure to see which sections ffprobe actually returned."],"exampleFix":"// before\nlet format = json\n    .get(\"format\")\n    .ok_or_else(|| anyhow!(\"Missing 'format' field\"))?;\n// after\nlet format = json.get(\"format\").ok_or_else(|| {\n    anyhow!(\n        \"Missing 'format' field in ffprobe output: {}\",\n        String::from_utf8_lossy(&output.stdout)\n    )\n})?;","handlingStrategy":"validation","validationCode":"let out = std::process::Command::new(\"ffprobe\")\n    .args([\"-v\", \"quiet\", \"-print_format\", \"json\", \"-show_format\", path])\n    .output()?;\nlet json: serde_json::Value = serde_json::from_slice(&out.stdout)?;\nif json.get(\"format\").is_none() {\n    return Err(\"input has no container format; not a regular media file\".into());\n}","typeGuard":"fn has_format_section(v: &serde_json::Value) -> bool {\n    v.get(\"format\").map(|f| f.is_object()).unwrap_or(false)\n}","tryCatchPattern":"match probe(path).await {\n    Err(e) if e.to_string() == \"Missing 'format' field\" => {\n        // treat as unsupported/invalid input file, skip metadata step\n        skip_duration(path);\n    }\n    other => other?,\n}","preventionTips":["Keep -show_format in the ffprobe argument list when touching the code","Validate inputs are regular files (not devices/pipes) before probing","Include the raw JSON in error context for diagnosability"],"tags":["ffmpeg","ffprobe","missing-field","json"],"backgroundTag":"unexpected-response-shape","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}