{"record":{"id":"17b2094e3029d264","repo":"tonhowtf/omniget","slug":"o-letterboxd-devolveu-uma-p-gina-em-vez-do-zip-a-sess-o","errorCode":null,"errorMessage":"o Letterboxd devolveu uma página em vez do ZIP — a sessão salva expirou; capture os cookies de novo","messagePattern":"o Letterboxd devolveu uma página em vez do ZIP — a sessão salva expirou; capture os cookies de novo","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/lists/letterboxd.rs","lineNumber":392,"sourceCode":"                ));\n            }\n            report(\n                &p,\n                TOOL_ID,\n                \"progress\",\n                0,\n                Some(3),\n                Some(EXPORT_URL.to_string()),\n            );\n            let (b, ctype) = f.get_bytes(EXPORT_URL).await?;\n            if ctype.contains(\"text/html\") || b.len() < 200 {\n                let body = String::from_utf8_lossy(&b);\n                if is_cloudflare_wall(&body) {\n                    return Err(anyhow!(\n                        \"o Cloudflare do Letterboxd barrou o download. Abra letterboxd.com no navegador, passe pelo \\\"Just a moment\\\" e capture os cookies de novo na extensão — o cf_clearance precisa vir junto\"\n                    ));\n                }\n                return Err(anyhow!(\n                    \"o Letterboxd devolveu uma página em vez do ZIP — a sessão salva expirou; capture os cookies de novo\"\n                ));\n            }\n            (b, EXPORT_URL.to_string())\n        }\n    };\n    if opts.keep_zip {\n        let _ = std::fs::write(dest.join(\"letterboxd-export.zip\"), &bytes);\n    }\n\n    // 2. Normalização.\n    report(\n        &p,\n        TOOL_ID,\n        \"progress\",\n        1,\n        Some(3),\n        Some(\"lendo o export\".into()),","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/lists/letterboxd.rs#L374-L410","documentation":"Same check as the Cloudflare-wall case (HTML response or body under 200 bytes from EXPORT_URL), but the body is NOT a Cloudflare challenge page. The tool concludes the session cookies no longer authenticate the download — Letterboxd served a generic HTML page (e.g. login or expired-session page) instead of the ZIP.","triggerScenarios":"Calling run without zip_path; f.get_bytes(EXPORT_URL) returns content-type containing 'text/html' or fewer than 200 bytes; is_cloudflare_wall is false; the saved cookies are stale/invalid/logged-out.","commonSituations":"Letterboxd session expired (weeks old cookies); user logged out of Letterboxd in the browser after capture; cookies captured for the wrong account or domain; Letterboxd invalidated sessions server-side.","solutions":["Re-capture fresh cookies from letterboxd.com while logged in, then re-run the tool.","Download the export manually at letterboxd.com/settings/data/ and pass opts.zip_path.","Log in to letterboxd.com in the browser to confirm the account session is actually alive.","Confirm the cookies file includes all Letterboxd cookies (not a partial/filtered capture)."],"exampleFix":"// before\nlet opts = Options { session_netscape: Some(\"captured-2-months-ago.txt\".into()), .. };\nrun(&opts, p).await?; // session expired\n// after\nlet opts = Options { session_netscape: Some(\"fresh_cookies.txt\".into()), .. }; // re-captured today\nrun(&opts, p).await?;","handlingStrategy":"retry","validationCode":"let cookies = std::fs::read_to_string(opts.session_netscape.as_deref().unwrap_or(\"\"))?;\nanyhow::ensure!(cookies.lines().any(|l| l.contains(\"letterboxd\")), \"cookies do Letterboxd ausentes no arquivo de sessão\");","typeGuard":"fn has_letterboxd_cookies(session_file: &str) -> bool {\n    std::fs::read_to_string(session_file)\n        .map(|c| c.lines().any(|l| l.contains(\"letterboxd\")))\n        .unwrap_or(false)\n}","tryCatchPattern":"match letterboxd::run(&opts, &p).await {\n    Err(e) if e.to_string().contains(\"sessão salva expirou\") => {\n        eprintln!(\"recapture os cookies de letterboxd.com e rode novamente\");\n        // retry once with fresh cookies\n    }\n    other => other?,\n}","preventionTips":["Stay logged in to letterboxd.com and re-capture cookies frequently","Confirm the session works by loading letterboxd.com right before running","Capture cookies for the correct account/domain","Fall back to a manually downloaded ZIP (zip_path) when automation fails repeatedly"],"tags":["letterboxd","session","cookies","http"],"backgroundTag":"session-expired","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"}