{"record":{"id":"c64c98ee1a086135","repo":"tonhowtf/omniget","slug":"n-o-achei-nenhum-v-deo-nessa-url-watch-later-precisa-da-sess","errorCode":null,"errorMessage":"não achei nenhum vídeo nessa URL (Watch Later precisa da sessão do YouTube)","messagePattern":"não achei nenhum vídeo nessa URL \\(Watch Later precisa da sessão do YouTube\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/yt_archive.rs","lineNumber":516,"sourceCode":"        ID,\n        \"progress\",\n        0,\n        None,\n        Some(\"lendo a coleção\".into()),\n    );\n    let mut args = vec![\n        \"-J\".to_string(),\n        \"--flat-playlist\".to_string(),\n        \"--no-warnings\".to_string(),\n        \"--ignore-errors\".to_string(),\n    ];\n    let cookie = CookieFile::new(opts.session_netscape.as_deref())?;\n    cookie.push_args(&mut args);\n    args.push(opts.url.trim().to_string());\n    let json = run_ytdlp(&args).await?;\n    let (title, items) = parse_flat_playlist(&json)?;\n    if items.is_empty() {\n        return Err(anyhow!(\n            \"não achei nenhum vídeo nessa URL (Watch Later precisa da sessão do YouTube)\"\n        ));\n    }\n    let mut st = load_state(dest).unwrap_or_else(|| ArchiveState::new(opts.url.trim(), &title));\n    st.source_url = opts.url.trim().to_string();\n    st.merge(&title, items, opts.retry_failed);\n    Ok(st)\n}\n\npub async fn run(opts: Options, progress: super::ProgressFn) -> anyhow::Result<ArchiveResult> {\n    if opts.dest.trim().is_empty() {\n        return Err(anyhow!(\"escolha a pasta do arquivo\"));\n    }\n    let dest = PathBuf::from(opts.dest.trim());\n    std::fs::create_dir_all(&dest)?;\n    CANCEL.store(false, Ordering::SeqCst);\n\n    let mut st = match load_state(&dest) {","sourceCodeStart":498,"sourceCodeEnd":534,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/yt_archive.rs#L498-L534","documentation":"enumerate runs yt-dlp to fetch a flat playlist and parses the resulting JSON; if parsing succeeds but yields zero video items, it throws \"não achei nenhum vídeo nessa URL (Watch Later precisa da sessão do YouTube)\". The hint exists because Watch Later (WL) playlists are private and only enumerate when authenticated with the user's YouTube session cookies.","triggerScenarios":"Calling scan or run with opts.url pointing to a playlist yt-dlp can see but that contains no items — notably a Watch Later URL without session_netscape cookies, or an empty/deleted playlist.","commonSituations":"Using the WL playlist URL without exporting YouTube cookies in Netscape format; cookies expired or from a different account; playlist URL typed wrong or now empty; region/account restrictions hiding items.","solutions":["Provide opts.session_netscape pointing to a fresh YouTube cookies file (export in Netscape format from a logged-in browser).","Re-export cookies if they are old — YouTube session cookies expire frequently.","Confirm the cookies file belongs to the account that owns the Watch Later playlist.","Open the playlist URL in a browser to verify it actually contains videos; try a different URL if it's empty or wrong.","Update yt-dlp if it fails to parse YouTube's current playlist page."],"exampleFix":"// before\nlet opts = Options { url: \"https://youtube.com/playlist?list=WL\".into(), dest: dest.clone(), session_netscape: None, retry_failed: false };\n// after\nlet opts = Options {\n    url: \"https://youtube.com/playlist?list=WL\".into(),\n    dest: dest.clone(),\n    session_netscape: Some(\"/home/user/youtube-cookies.txt\".into()),\n    retry_failed: false,\n};","handlingStrategy":"validation","validationCode":"// Rust\nlet is_watch_later = opts.url.contains(\"list=WL\");\nif is_watch_later && opts.session_netscape.is_none() {\n    return Err(anyhow!(\"Watch Later exige cookies de sessão (session_netscape)\"));\n}","typeGuard":null,"tryCatchPattern":"match yt_archive::scan(&opts, &progress).await {\n    Ok(r) => r,\n    Err(e) if e.to_string().contains(\"nenhum vídeo\") => {\n        eprintln!(\"playlist vazia ou sem sessão; forneça cookies do YouTube e tente de novo\");\n        prompt_for_cookies()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always supply a fresh Netscape-format YouTube cookies file for Watch Later playlists","Re-export cookies when enumeration suddenly returns empty","Confirm the playlist has videos by opening it in a logged-in browser","Verify cookies belong to the account owning the playlist"],"tags":["youtube","yt-dlp","authentication","empty-playlist"],"backgroundTag":"authentication-required","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"}