{"record":{"id":"8c70621fcaafceba","repo":"tonhowtf/omniget","slug":"ffmpeg-nao-iniciou-sticker","errorCode":null,"errorMessage":"ffmpeg nao iniciou: {}","messagePattern":"ffmpeg nao iniciou: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"src-tauri/omniget-core/src/core/tools/sticker.rs","lineNumber":487,"sourceCode":"            &spec,\n            &attempt,\n            bitrate,\n            &inp.to_string_lossy(),\n            &output.to_string_lossy(),\n        );\n        super::report(\n            progress,\n            ID,\n            \"progress\",\n            tries as u64,\n            None,\n            Some(format!(\"{} · q{}\", stem, attempt.quality)),\n        );\n        let out = crate::core::process::command(ffmpeg)\n            .args(&args)\n            .output()\n            .await\n            .map_err(|e| anyhow!(\"ffmpeg nao iniciou: {}\", e))?;\n        if !out.status.success() {\n            let msg = String::from_utf8_lossy(&out.stderr).trim().to_string();\n            // Falhar já no primeiro degrau é erro de verdade (codec ausente,\n            // arquivo corrompido); nos degraus seguintes já existe um arquivo\n            // bom na mão, então vale ficar com ele.\n            if best.is_none() {\n                return Err(anyhow!(\"{}\", msg));\n            }\n            tracing::warn!(\n                \"[wa-sticker] tentativa q{} falhou: {}\",\n                attempt.quality,\n                msg\n            );\n            break;\n        }\n        let bytes = std::fs::metadata(&output).map(|m| m.len()).unwrap_or(0);\n        best = Some((bytes, attempt));\n        if bytes <= spec.max_bytes {","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/sticker.rs#L469-L505","documentation":"In `convert_one` (sticker.rs), the sticker conversion shells out to an external `ffmpeg` binary via `crate::core::process::command(...).output().await`. If spawning the process itself fails (the error returned by `output()`), it is wrapped as \"ffmpeg nao iniciou: {e}\". This means ffmpeg could not be launched at all — typically because the binary does not exist, is not on PATH, or lacks execute permission. This is distinct from ffmpeg running but failing (non-zero exit), which is handled separately.","triggerScenarios":"Calling sticker conversion on any animated/converted target when the ffmpeg executable is not installed, not found in PATH, the configured ffmpeg path is wrong, or the binary lacks the execute bit; also on platforms where `std::process::Command::output` fails for spawn reasons (e.g. fork/ENOMEM).","commonSituations":"Fresh machines or Docker images without ffmpeg installed; bundlers that fail to ship the sidecar ffmpeg binary with the Tauri app; PATH not containing ffmpeg when launched from a GUI session; corrupted/zero-permission ffmpeg download.","solutions":["Install ffmpeg and ensure it is on PATH (`ffmpeg -version` must succeed in the same environment the app runs in).","If the app bundles ffmpeg (Tauri sidecar), verify the sidecar binary exists at the resolved path and has the executable bit set.","Check the wrapped source error (`e`) in \"ffmpeg nao iniciou: {}\" — NotFound means wrong path, PermissionDenied means chmod +x.","If a custom ffmpeg path is configurable, validate it at startup (spawn `ffmpeg -version`) and fail fast with a clear setup message.","For GUI launches on Linux/macOS, note PATH differs from the shell; use an absolute ffmpeg path instead of relying on PATH."],"exampleFix":"// before\nlet out = crate::core::process::command(ffmpeg)\n    .args(&args)\n    .output()\n    .await\n    .map_err(|e| anyhow!(\"ffmpeg nao iniciou: {}\", e))?;\n\n// after\nif !ffmpeg.exists() {\n    return Err(anyhow!(\n        \"ffmpeg nao encontrado em {}; instale o ffmpeg ou ajuste o caminho\",\n        ffmpeg.display()\n    ));\n}\nlet out = crate::core::process::command(ffmpeg)\n    .args(&args)\n    .output()\n    .await\n    .map_err(|e| anyhow!(\"ffmpeg nao iniciou: {}\", e))?;","handlingStrategy":"try-catch","validationCode":"fn ffmpeg_available(cmd: &str) -> bool {\n    std::process::Command::new(cmd).arg(\"-version\").output()\n        .map(|o| o.status.success())\n        .unwrap_or(false)\n}\n// call once at startup; abort conversion features if false","typeGuard":null,"tryCatchPattern":"match convert_one(&opts, input, progress).await {\n    Err(e) if e.to_string().starts_with(\"ffmpeg nao iniciou\") => {\n        eprintln!(\"instale o ffmpeg ou verifique o caminho configurado\");\n        // optionally retry with a bundled sidecar ffmpeg path\n    }\n    r => { r?; }\n}","preventionTips":["Probe `ffmpeg -version` at app startup and degrade features gracefully","Bundle ffmpeg as a Tauri sidecar and use its absolute path instead of PATH lookup","Set the execute bit on bundled binaries after download/extraction","On GUI launches (Linux/macOS) never rely on shell PATH; resolve absolute ffmpeg path"],"tags":["ffmpeg","external-process","missing-dependency","media-conversion"],"backgroundTag":"missing-dependency","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"}