{"record":{"id":"74c484f1d7ed5359","repo":"tonhowtf/omniget","slug":"ghostscript-nao-encontrado","errorCode":null,"errorMessage":"Ghostscript nao encontrado","messagePattern":"Ghostscript nao encontrado","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pdf.rs","lineNumber":1183,"sourceCode":"            .unwrap_or(0);\n            report(&progress, \"done\", 1, Some(1), None);\n            return Ok(CompressResult {\n                output: output.to_string_lossy().to_string(),\n                before,\n                after,\n                method: \"ghostscript\".into(),\n                pages,\n            });\n        }\n        if opts.mode == \"gs\" {\n            return Err(anyhow!(\n                \"ghostscript falhou: {}\",\n                String::from_utf8_lossy(&o.stderr).trim()\n            ));\n        }\n        let _ = std::fs::remove_file(&output);\n    } else if opts.mode == \"gs\" {\n        return Err(anyhow!(\"Ghostscript nao encontrado\"));\n    }\n    let dpi = if opts.dpi == 0 { 110 } else { opts.dpi };\n    let quality = if opts.quality == 0 { 60 } else { opts.quality };\n    let out =\n        tokio::task::spawn_blocking(move || rasterize(&input, &output, dpi, quality, &progress))\n            .await??;\n    Ok(CompressResult {\n        output: out.output,\n        before,\n        after: out.bytes,\n        method: \"raster\".into(),\n        pages: out.pages,\n    })\n}\n\n/// Dangerzone sem contêiner: cada página vira pixels e o PDF é remontado\n/// só com imagens. Scripts, formulários, links e anexos não sobrevivem.\npub fn sanitize(","sourceCodeStart":1165,"sourceCodeEnd":1201,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pdf.rs#L1165-L1201","documentation":"When compression mode is \"gs\" but the ghostscript executable cannot be located on the system, the tool throws \"Ghostscript nao encontrado\" (\"Ghostscript not found\") instead of attempting compression. Raster-based compression can proceed, but explicit gs mode cannot without the binary.","triggerScenarios":"Calling compress with opts.mode == \"gs\" on a machine where the gs/ghostscript binary is not installed or is absent from PATH.","commonSituations":"Fresh OS installs without ghostscript; Windows users without gs in PATH; Docker/CI images stripped of ghostscript; sandboxed Tauri environments with a minimal PATH.","solutions":["Install ghostscript (apt install ghostscript / brew install ghostscript / choco install ghostscript).","Ensure the gs binary's directory is on PATH for the app process.","Use a different compression mode that doesn't require ghostscript.","In Docker, add ghostscript to the image packages."],"exampleFix":"// Dockerfile before\nFROM ubuntu:24.04\n\n// after\nFROM ubuntu:24.04\nRUN apt-get update && apt-get install -y ghostscript","handlingStrategy":"fallback","validationCode":"fn ghostscript_available() -> bool {\n    std::process::Command::new(\"gs\").arg(\"--version\").output()\n        .map(|o| o.status.success()).unwrap_or(false)\n}\n// choose mode: if !ghostscript_available() && opts.mode == \"gs\" { opts.mode = \"raster\".into(); }","typeGuard":null,"tryCatchPattern":"let result = compress(&opts, &progress).await;\nmatch result {\n    Err(e) if e.to_string().contains(\"Ghostscript nao encontrado\") => {\n        let mut fallback_opts = opts.clone();\n        fallback_opts.mode = \"raster\".into(); // path that does not need gs\n        compress(&fallback_opts, &progress).await\n    }\n    other => other,\n}","preventionTips":["Install ghostscript in every environment the app runs in (dev, CI, Docker, user machines).","Probe for `gs --version` at app startup and degrade features gracefully.","Add ghostscript to installers/package dependencies.","On Windows, ship or detect the gswin64c binary and map PATH accordingly."],"tags":["pdf","ghostscript","missing-binary","environment","rust"],"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"}