{"record":{"id":"61ecbc03a0ca7201","repo":"tonhowtf/omniget","slug":"nenhuma-chave-selecionada","errorCode":null,"errorMessage":"nenhuma chave selecionada","messagePattern":"nenhuma chave selecionada","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/ai_keys.rs","lineNumber":519,"sourceCode":"        _ => return Err(anyhow!(\"este provedor nao expoe saldo pela API\")),\n    };\n    update(id, |e| e.balance = Some(text))\n}\n\n// ── Exportar ───────────────────────────────────────────────────────────\n\nfn is_openai_compatible(kind: &str) -> bool {\n    !matches!(kind, \"anthropic\" | \"gemini\")\n}\n\npub fn export(format: &str, ids: &[String]) -> anyhow::Result<String> {\n    let _g = LOCK.lock().unwrap_or_else(|e| e.into_inner());\n    let list: Vec<KeyEntry> = load()\n        .into_iter()\n        .filter(|e| ids.is_empty() || ids.contains(&e.id))\n        .collect();\n    if list.is_empty() {\n        return Err(anyhow!(\"nenhuma chave selecionada\"));\n    }\n    let slug = |s: &str| {\n        s.chars()\n            .map(|c| {\n                if c.is_ascii_alphanumeric() {\n                    c.to_ascii_lowercase()\n                } else {\n                    '_'\n                }\n            })\n            .collect::<String>()\n    };\n    Ok(match format {\n        \"env\" => {\n            let mut out = String::new();\n            for e in &list {\n                let k = kind_of(&e.kind);\n                out.push_str(&format!(\"# {} ({})\\n\", e.name, k.name));","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/ai_keys.rs#L501-L537","documentation":"export() loads all stored key entries and filters by the requested ids; if the resulting list is empty it throws 'nenhuma chave selecionada'. This guards against exporting an empty key set — either no keys exist at all or none of the given ids match stored entries.","triggerScenarios":"Calling export(ids, format) with an empty vault, or with id strings that do not match any stored key entry (stale ids after deletion, typos, ids from another machine's vault).","commonSituations":"UI passes a selection that was deleted concurrently; caller hardcodes ids copied from a different installation; fresh install with no keys added yet.","solutions":["Add at least one API key in the key manager before exporting.","Verify the ids passed to export exist (list keys first and use returned ids).","Call export with an empty ids slice to export all keys instead of an empty selection.","Refresh the UI list after deletions so stale ids aren't sent."],"exampleFix":"// before\nexport(vec![\"key-123\".into()], \"opencode\")  // key already deleted\n// after\nlet all = list_keys();\nexport(all.iter().map(|k| k.id.clone()).collect(), \"opencode\")","handlingStrategy":"validation","validationCode":"// ensure selection is non-empty and ids are current\nlet ids: Vec<String> = selected_ids;\nlet stored: Vec<String> = list_keys()?.into_iter().map(|k| k.id).collect();\nlet valid: Vec<&String> = ids.iter().filter(|i| stored.contains(i)).collect();\nif valid.is_empty() { eprintln!(\"no matching keys to export\"); return; }","typeGuard":"fn has_exportable(ids: &[String], keys: &[KeyEntry]) -> bool {\n    ids.is_empty() || keys.iter().any(|k| ids.contains(&k.id))\n}","tryCatchPattern":"match export(&ids, \"opencode\") {\n    Ok(json) => save(json),\n    Err(e) if e.to_string().contains(\"nenhuma chave selecionada\") => {\n        eprintln!(\"vault empty or stale ids — refresh the key list\");\n    }\n    Err(e) => show_error(e),\n}","preventionTips":["Refresh id lists after any add/delete operation","Export all keys (empty ids) when no explicit selection exists","Validate ids against list_keys() before exporting","Guard against empty vaults in the calling UI"],"tags":["empty-input","export","state"],"backgroundTag":"empty-result-set","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"}