tonhowtf/omniget · error

o export veio sem nenhum livro

Error message

o export veio sem nenhum livro

What it means

Thrown after the tool parses the Goodreads CSV export with parse_export_csv: if the parsed entry list is empty — meaning no book rows were recognized — run() aborts. The CSV may exist and even contain 'title', but zero books were extracted from it.

Solutions

  1. Open the CSV and confirm it contains book rows beyond the header line.
  2. Re-export from goodreads.com/review/import to get a complete, current file.
  3. Check whether the Goodreads export format changed and update parse_export_csv's column mapping.
  4. Ensure you're passing the correct file (goodreads_library_export.csv), not another CSV.

Example fix

// before
let csv = std::fs::read_to_string("some_other_export.csv")?;
run(&opts, p).await?;
// after
let csv = std::fs::read_to_string("goodreads_library_export.csv")?;
assert!(csv.lines().count() > 1, "export has no data rows");
run(&opts, p).await?;
Defensive patterns

Strategy: validation

Validate before calling

let csv = std::fs::read_to_string("goodreads_library_export.csv")?;
let data_rows = csv.lines().skip(1).filter(|l| !l.trim().is_empty()).count();
anyhow::ensure!(data_rows > 0, "export do Goodreads não tem livros: {data_rows} linhas de dados");

Type guard

fn goodreads_export_has_rows(csv: &str) -> bool {
    csv.lines().skip(1).any(|l| !l.trim().is_empty())
}

Try / catch

match run(&opts, &p).await {
    Err(e) if e.to_string().contains("sem nenhum livro") => {
        eprintln!("o CSV está vazio ou ilegível — re-exporte em goodreads.com/review/import");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling run with an export file that has headers but no data rows (e.g. an account with an empty library), a truncated/corrupt CSV, or a CSV whose columns don't match what parse_export_csv expects.

Common situations: User selected the wrong CSV file (some other tool's export that happens to contain 'title'); freshly created Goodreads account with no books; partial download cut off mid-file; Goodreads changed column names so the parser matches nothing.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/2936cd1b4bd3c546. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/lists/goodreads.rs:537

            std::fs::read_to_string(path).with_context(|| format!("não consegui ler {}", path))?,
            path.to_string(),
            0,
        ),
        _ => {
            if !f.has_session() {
                return Err(anyhow!(
                    "sem sessão do Goodreads: capture os cookies de goodreads.com na extensão, ou aponte o goodreads_library_export.csv que você já baixou"
                ));
            }
            let (csv, secs) = trigger_and_wait(&f, opts, &p).await?;
            let _ = std::fs::write(dest.join("goodreads_library_export.csv"), &csv);
            (csv, EXPORT_BASE.to_string(), secs)
        }
    };

    let mut entries = parse_export_csv(&csv);
    if entries.is_empty() {
        return Err(anyhow!("o export veio sem nenhum livro"));
    }

    // Reviews que o CSV não trouxe, buscadas na prateleira.
    let mut enriched = 0usize;
    if !opts.enrich_shelves.is_empty() && f.has_session() {
        let page = f.get_text(IMPORT_URL).await.unwrap_or_default();
        match user_id(&page) {
            None => tracing::debug!("gr-export: não achei o id do usuário; pulei o enriquecimento"),
            Some(uid) => {
                let mut found: HashMap<String, String> = HashMap::new();
                for shelf in &opts.enrich_shelves {
                    for page_n in 1..=opts.max_pages.max(1) {
                        report(
                            &p,
                            TOOL_ID,
                            "progress",
                            page_n as u64,
                            Some(opts.max_pages as u64),

View on GitHub (pinned to 8600b91f42)