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

  1. Check the PDF is actually encrypted before invoking (qpdf --show-encryption file.pdf, or doc.is_encrypted())
  2. Only call password(mode="remove") for documents reported as password-protected
  3. 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

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)