tonhowtf/omniget · error
não gravei
Error message
não gravei {}: {} What it means
This error is raised in the redaction tool's `run` when `doc.save(&output)` fails after redaction regions were applied. It wraps the underlying PDF write error with the output path and original error text via `anyhow!`, so the message literally means 'did not write <path>: <cause>'. It indicates the redacted document could not be persisted to disk.
Solutions
- Check the underlying error text after the colon — it names the real cause (NotFound, PermissionDenied, storage full, etc.)
- Verify the output directory exists and is writable before running redaction
- Close any program that has the output file open (viewers keep write locks on Windows)
- Free disk space or write to a different volume
- If the PDF library fails to serialize, try saving to a fresh temp path then rename into place
Example fix
// before
let out = PathBuf::from("C:/Program Files/app/output.pdf");
doc.save(&out).map_err(|e| anyhow!("não gravei {}: {}", out.display(), e))?;
// after
let out = dirs::document_dir().unwrap().join("redacted.pdf");
if let Some(parent) = out.parent() { std::fs::create_dir_all(parent)?; }
doc.save(&out).map_err(|e| anyhow!("não gravei {}: {}", out.display(), e))?; Defensive patterns
Strategy: try-catch
Validate before calling
// Rust
fn ensure_writable(path: &std::path::Path) -> anyhow::Result<()> {
let dir = path.parent().ok_or_else(|| anyhow!("sem diretório"))?;
if !dir.exists() { std::fs::create_dir_all(dir)?; }
let probe = dir.join(".write_probe");
std::fs::write(&probe, b"")?;
std::fs::remove_file(&probe)?;
if path.exists() && std::fs::metadata(path)?.permissions().readonly() {
anyhow::bail!("arquivo de saída é read-only");
}
Ok(())
} Type guard
fn is_writable_output(path: &std::path::Path) -> bool {
path.parent().map(|d| d.is_dir()).unwrap_or(false)
&& std::fs::OpenOptions::new().append(true).create(true)
.open(path).is_ok()
} Try / catch
match run(/* ... */) {
Err(e) if e.to_string().starts_with("não gravei") => {
eprintln!("falha ao gravar o PDF: {}. Verifique permissões e espaço em disco.", e);
}
Err(e) => return Err(e),
Ok(report) => { /* success */ }
} Prevention
- Always create the output parent directory with create_dir_all before saving
- Save to a temp file in the same directory and rename on success (atomic write)
- Pre-check disk free space for raster-mode output, which can be much larger
- Prompt the user to close PDF viewers before writing to an existing file
When it happens
Trigger: Calling `run` (via `live_redact_deixa_o_check_limpo`) where the output path is unwritable: invalid directory, missing parent folder, permission denied, disk full, path locked by another process, or a failure inside the PDF library while serializing the modified document.
Common situations: Output directory was deleted or renamed between selection and save; running the app without write permission to the chosen folder; saving to a file still open in a PDF viewer (Windows file locking); disk quota/full disk; output path containing invalid characters for the filesystem.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/d72cc28a9dd4c958.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/pdf_redact.rs:893
Some(raw) => redact_page(&mut doc, page_id, raw, rs, opts.bar)?,
None => (false, 0, "página não abriu no PDFium".to_string()),
}
};
if !surgical {
fallback.push(*no);
}
chars_removed += removed;
by_page.push(PageReport {
page: *no,
areas: rs.len(),
chars_removed: removed,
mode: if surgical { "text" } else { "raster" }.into(),
note,
});
}
doc.save(&output)
.map_err(|e| anyhow!("não gravei {}: {}", output.display(), e))?;
// Conferência: o que ainda aparece dentro da região tem que virar pixel.
report(progress, "progress", 2, 4, Some("conferindo".into()));
let mut leftovers = 0usize;
let out_s = output.to_string_lossy().to_string();
if let Ok(after) = pdf::read_raw_chars(&out_s, None, "") {
for page in &after {
let Some(rs) = rects.get(&page.number) else {
continue;
};
let n = page
.chars
.iter()
.filter(|c| !c.ch.is_whitespace() && !c.empty_box())
.filter(|c| {
let (cx, cy) = c.center();
any_inside(rs, cx, cy)
})View on GitHub (pinned to 8600b91f42)