{"record":{"id":"09a1ea151ed9734e","repo":"tonhowtf/omniget","slug":"a-sess-o-do-medium-n-o-listou-nenhuma-hist-ria-sua-a-sess-o","errorCode":null,"errorMessage":"a sessão do Medium não listou nenhuma história sua (a sessão pode ter expirado)","messagePattern":"a sessão do Medium não listou nenhuma história sua \\(a sessão pode ter expirado\\)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/blogs/medium.rs","lineNumber":770,"sourceCode":"}\n\nasync fn from_session(\n    fetcher: &Fetcher,\n    opts: &Options,\n    progress: &ProgressFn,\n) -> Result<Vec<PostDoc>> {\n    let mut refs: Vec<StoryRef> = Vec::new();\n    crate::core::tools::report(&progress.clone(), ID, \"list\", 0, None, None);\n    let public = fetcher.get_json(&list_url(\"public\")).await?;\n    refs.extend(parse_story_list(&public, false));\n    if opts.drafts {\n        match fetcher.get_json(&list_url(\"drafts\")).await {\n            Ok(v) => refs.extend(parse_story_list(&v, true)),\n            Err(e) => tracing::warn!(\"medium: rascunhos não vieram: {}\", e),\n        }\n    }\n    if refs.is_empty() {\n        return Err(anyhow!(\n            \"a sessão do Medium não listou nenhuma história sua (a sessão pode ter expirado)\"\n        ));\n    }\n    if opts.limit > 0 && refs.len() > opts.limit {\n        refs.truncate(opts.limit);\n    }\n\n    let mut docs = Vec::new();\n    let total = refs.len() as u64;\n    for (i, r) in refs.iter().enumerate() {\n        if fetcher.requests() >= opts.max_requests {\n            break;\n        }\n        crate::core::tools::report(\n            progress,\n            ID,\n            \"story\",\n            i as u64,","sourceCodeStart":752,"sourceCodeEnd":788,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/blogs/medium.rs#L752-L788","documentation":"from_session() lists your stories (public and drafts) using the authenticated Medium session. If the session responded successfully but parsed to zero story references, the exporter assumes the session is stale/expired and throws this error instead of exporting nothing.","triggerScenarios":"Calling run() with session cookies enabled such that from_session runs; list_url(\"drafts\") and the other listing endpoints returned JSON that parse_story_list converted to an empty refs list (or only drafts fetch errors were logged as warnings).","commonSituations":"Expired or revoked medium.com session cookies; cookies captured from a different browser profile than the logged-in account; Medium changed the private listing API shape so parse_story_list finds no stories.","solutions":["Re-capture fresh medium.com cookies in the session manager and retry","Log in to medium.com in the browser to confirm the session is actually valid","Fall back to the public RSS feed path by setting opts.user","If the API shape changed, update parse_story_list to match the current Medium JSON schema"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before calling run with session mode, verify cookies work:\nlet probe = fetcher.get_json(&list_url(\"drafts\")).await;\nif probe.is_err() { /* ask user to re-capture cookies */ }","typeGuard":null,"tryCatchPattern":"match run(&opts, progress).await {\n    Err(e) if e.to_string().contains(\"sessão do Medium\") => {\n        reauthenticate_and_retry().await?;\n    }\n    other => other?,\n}","preventionTips":["Refresh medium.com cookies regularly; they expire","Confirm the browser session is alive before capturing cookies","Keep the public-feed fallback (opts.user) configured as backup"],"tags":["medium","session","authentication"],"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"}