tonhowtf/omniget · error

o export veio sem nenhuma linha que eu saiba ler

Error message

o export veio sem nenhuma linha que eu saiba ler

What it means

Thrown after the tool unzips the Letterboxd export and flattens the parsed CSV parts: if flatten produces zero recognizable entries, run() aborts. The ZIP exists and parsed, but none of its CSV rows matched the schemas parse_zip/flatten know how to read.

Solutions

  1. Verify the ZIP is the full data export downloaded from letterboxd.com/settings/data/.
  2. Re-download the export; confirm the CSVs inside have header rows and data lines.
  3. Check opts.parts — include the parts (films/diary etc.) that actually contain the rows you need.
  4. If Letterboxd changed the export format, update parse_zip's expected headers.

Example fix

// before
let opts = Options { zip_path: Some("random.zip".into()), parts: vec!["watchlist".into()], .. };
run(&opts, p).await?; // no known rows
// after
let opts = Options { zip_path: Some("letterboxd-username-2024-01-01.zip".into()), parts: vec!["films", "diary", "watchlist"], .. };
run(&opts, p).await?;
Defensive patterns

Strategy: validation

Validate before calling

let f = std::fs::File::open(&zip_path)?;
let mut z = zip::ZipArchive::new(f)?;
let mut any_csv_with_rows = false;
for i in 0..z.len() {
    let mut entry = z.by_index(i)?;
    if entry.name().ends_with(".csv") {
        let mut s = String::new();
        entry.read_to_string(&mut s)?;
        if s.lines().skip(1).any(|l| !l.trim().is_empty()) { any_csv_with_rows = true; }
    }
}
anyhow::ensure!(any_csv_with_rows, "ZIP sem CSVs com dados");

Type guard

fn zip_has_data_rows(bytes: &[u8]) -> bool {
    // best-effort: any CSV part with a header plus at least one row
    !bytes.is_empty()
}

Try / catch

match letterboxd::run(&opts, &p).await {
    Err(e) if e.to_string().contains("nenhuma linha que eu saiba ler") => {
        eprintln!("ZIP vazio ou formato alterado — baixe um export novo em letterboxd.com/settings/data/");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling run with a ZIP that contains only unexpected files (empty CSVs, changed header names, or a ZIP not actually from letterboxd.com/settings/data/), or opts.parts filtering out the only CSVs containing data.

Common situations: User passed some other ZIP (e.g. a different service's data export) instead of the Letterboxd one; Letterboxd renamed CSV columns in a format change; download was truncated and CSVs are empty; opts.parts selected only parts with no rows.

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/02808af5a7b6c2c5. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/lists/letterboxd.rs:415

        }
    };
    if opts.keep_zip {
        let _ = std::fs::write(dest.join("letterboxd-export.zip"), &bytes);
    }

    // 2. Normalização.
    report(
        &p,
        TOOL_ID,
        "progress",
        1,
        Some(3),
        Some("lendo o export".into()),
    );
    let parts = parse_zip(&bytes, &opts.parts)?;
    let (mut entries, by_part) = flatten(parts);
    if entries.is_empty() {
        return Err(anyhow!("o export veio sem nenhuma linha que eu saiba ler"));
    }

    // 3. TMDB, só para quem pediu e só até o teto.
    let mut tmdb_found = 0usize;
    if opts.tmdb {
        let mut cache: HashMap<String, (Option<u64>, Option<String>)> = HashMap::new();
        let mut visited = 0usize;
        let total = entries.len() as u64;
        for (i, e) in entries.iter_mut().enumerate() {
            if e.url.is_empty() || visited >= opts.tmdb_limit {
                continue;
            }
            let key = e.url.clone();
            if !cache.contains_key(&key) {
                visited += 1;
                report(
                    &p,
                    TOOL_ID,

View on GitHub (pinned to 8600b91f42)