tonhowtf/omniget · error

o Goodreads recusou o pedido de export

Error message

o Goodreads recusou o pedido de export (HTTP {}). Ele só deixa gerar um a cada poucos dias

What it means

After POSTing to /review_porter/export/<id>, trigger_and_wait accepts success (2xx) or a 302 redirect; any other non-success status means Goodreads refused the export request. Since Goodreads rate-limits export generation to once every few days, the error message explicitly calls out that restriction.

Solutions

  1. Don't force a new export: rerun with force=false so the existing ready export link is reused instead of POSTing again.
  2. Wait a few days for Goodreads' export cooldown to lapse before forcing a new export.
  3. Recapture cookies (a stale CSRF token can cause rejection) and retry once.
  4. If HTTP 429, back off significantly — repeated attempts prolong any rate-limit block.

Example fix

// before
run(&f, &Options { force: true, .. }).await?; // rejected, export already made this week

// after
run(&f, &Options { force: false, .. }).await?; // reuse existing export link
Defensive patterns

Strategy: retry

Validate before calling

// don't attempt a forced export if a ready one exists
let page = fetcher.get_text(IMPORT_URL).await?;
let opts = if export_link(&page).is_some() {
    Options { force: false, ..opts }
} else { opts };

Try / catch

match run(&fetcher, &opts).await {
    Err(e) if e.to_string().contains("recusou o pedido de export") => {
        eprintln!("Export cooldown active; rerun later with force=false");
    }
    r => r?,
}

Prevention

When it happens

Trigger: The export-trigger POST returns e.g. 403/429/500: requesting an export sooner than Goodreads' cooldown allows, an invalid/expired CSRF token, or a rate-limited/blocked session.

Common situations: User (or this tool) already generated an export within the last few days and force=true was set; CSRF token mismatch from stale cookies; aggressive retry loop tripping Goodreads rate limiting.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

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

        f.pace().await;
        let resp = f
            .client()
            .post(export_post_url(&uid))
            .header(reqwest::header::REFERER, IMPORT_URL)
            .header(reqwest::header::ORIGIN, "https://www.goodreads.com")
            .header(reqwest::header::ACCEPT, "*/*")
            .header("X-Requested-With", "XMLHttpRequest")
            .header("X-CSRF-Token", token)
            .header(
                reqwest::header::CONTENT_TYPE,
                "application/x-www-form-urlencoded",
            )
            .body("format=json")
            .send()
            .await?;
        let status = resp.status();
        if !status.is_success() && status.as_u16() != 302 {
            return Err(anyhow!(
                "o Goodreads recusou o pedido de export (HTTP {}). Ele só deixa gerar um a cada poucos dias",
                status
            ));
        }
    }

    // Espera: o CSV é gerado em segundo plano e responde 404 até ficar pronto.
    let limit = Duration::from_secs(opts.wait_secs.clamp(30, 3600));
    loop {
        let code = f.head_status(&csv_url).await.unwrap_or(0);
        if code == 200 {
            break;
        }
        if code != 404 && code != 0 && code != 403 {
            return Err(anyhow!(
                "o Goodreads respondeu HTTP {} no arquivo do export",
                code
            ));

View on GitHub (pinned to 8600b91f42)