tonhowtf/omniget · warning
esse PDF não tem senha
Error message
esse PDF não tem senha
What it means
password_one in 'remove' mode requires an actually-encrypted document. If doc.is_encrypted() is false AND no current_password was supplied, there is nothing to strip, so the function returns 'esse PDF não tem senha' instead of pointlessly rewriting the file.
Solutions
- Check the PDF is actually encrypted before invoking (qpdf --show-encryption file.pdf, or doc.is_encrypted())
- Only call password(mode="remove") for documents reported as password-protected
- If the intent was to add a password, use the add/set mode instead of "remove"
Example fix
// before
password_one(&PasswordOptions { mode: "remove", ..Default::default() }, input)?;
// after
if is_pdf_encrypted(input) {
password_one(&PasswordOptions { mode: "remove", ..Default::default() }, input)?;
} Defensive patterns
Strategy: validation
Validate before calling
if mode == "remove" && !is_pdf_encrypted(input) && current_password.is_empty() {
anyhow::bail!("nada a remover: o PDF já está aberto");
} Try / catch
match password_one(&opts, input) {
Ok(item) => item,
Err(e) if e.to_string().contains("não tem senha") => Ok(WriteItem::noop(input)),
Err(e) => return Err(e),
} Prevention
- Detect encryption (is_encrypted / qpdf --show-encryption) before remove mode
- Treat 'already unprotected' as a no-op success in UI flows
- Skip queueing unprotected files for password removal
When it happens
Trigger: Calling password with mode="remove" on a PDF that has no encryption dictionary and no current_password set in PasswordOptions.
Common situations: User drags an unprotected PDF into a 'remove password' flow; a previous run already removed the password; caller misinterprets 'remove' mode as generic re-save.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/1bf55b9bde4f5859.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/pdf_write.rs:125
}
fn load(input: &str, password: &str) -> anyhow::Result<Document> {
let doc = if password.is_empty() {
Document::load(input)
} else {
let bytes = std::fs::read(input)?;
Document::load_mem_with_options(&bytes, lopdf::LoadOptions::with_password(password))
};
doc.map_err(|e| anyhow!("não abri o PDF: {}", e))
}
fn password_one(opts: &PasswordOptions, input: &str) -> anyhow::Result<WriteItem> {
let mut doc = load(input, &opts.current_password)?;
let pages = doc.get_pages().len();
let note;
if opts.mode == "remove" {
if !doc.is_encrypted() && opts.current_password.is_empty() {
return Err(anyhow!("esse PDF não tem senha"));
}
// `load_mem_with_password` já devolve o documento decifrado; basta
// apagar o dicionário de cifra para o arquivo sair aberto.
doc.encryption_state = None;
doc.trailer.remove(b"Encrypt");
note = "senha removida".to_string();
} else {
if opts.user_password.is_empty() && opts.owner_password.is_empty() {
return Err(anyhow!("defina pelo menos uma senha"));
}
let owner = if opts.owner_password.is_empty() {
opts.user_password.as_str()
} else {
opts.owner_password.as_str()
};
// A derivação da chave usa o /ID do arquivo. PDF gerado por
// ferramenta simples costuma não ter: sem isso a cifra falha com um
// "decryption error" que não diz nada.View on GitHub (pinned to 8600b91f42)