tonhowtf/omniget · error
defina pelo menos uma senha
Error message
defina pelo menos uma senha
What it means
When adding/setting a password, password_one demands at least one of user_password or owner_password. If both strings are empty there is no secret to build an EncryptionState from, so the function bails with 'defina pelo menos uma senha'.
Solutions
- Set opts.user_password to require a password to open, or opts.owner_password to lock permissions only
- Validate in the caller/UI that at least one password field is non-empty before invoking
- If the goal was only to remove a password, switch mode to "remove"
Example fix
// before
let opts = PasswordOptions { mode: "add".into(), ..Default::default() };
password_one(&opts, input)?;
// after
let opts = PasswordOptions { mode: "add".into(), user_password: "s3cret".into(), ..Default::default() };
assert!(!opts.user_password.is_empty() || !opts.owner_password.is_empty());
password_one(&opts, input)?; Defensive patterns
Strategy: validation
Validate before calling
if opts.user_password.trim().is_empty() && opts.owner_password.trim().is_empty() {
anyhow::bail!("informe a senha do usuário ou do proprietário");
} Try / catch
match password_one(&opts, input) {
Ok(item) => item,
Err(e) if e.to_string().contains("defina pelo menos uma senha") => {
eprintln!("informe user_password ou owner_password");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Require non-empty password fields in UI forms before submit
- Never construct PasswordOptions with all-empty passwords for add/set modes
- Trim passwords and reject whitespace-only values
When it happens
Trigger: Calling password with mode != "remove" and both opts.user_password and opts.owner_password empty strings.
Common situations: UI form submitted with blank password fields; caller defaults all PasswordOptions fields to empty strings; config file with unset password keys.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- escolha o PDF
- escreva o texto da marca d'água
- documento sem páginas
- escolha a pasta de destino
- escolha a pasta de destino
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/76542712ac4bc470.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/pdf_write.rs:134
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.
if doc.trailer.get(b"ID").is_err() {
use rand::RngExt;
let mut id = [0u8; 16];
rand::rng().fill(&mut id);
let id = hex::encode(id).into_bytes();
doc.trailer.set(
"ID",
Object::Array(vec![
Object::string_literal(id.clone()),View on GitHub (pinned to 8600b91f42)