{"record":{"id":"dd2e5f8f6f40e3a0","repo":"tonhowtf/omniget","slug":"nao-reconheci-um-post-do-x-em","errorCode":null,"errorMessage":"nao reconheci um post do X em: {}","messagePattern":"nao reconheci um post do X em: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/x/thread.rs","lineNumber":36,"sourceCode":"    pub source: String,\n}\n\nimpl Thread {\n    pub fn title(&self) -> String {\n        let first = self.posts.first().unwrap_or(&self.focal);\n        let line = first.text.lines().next().unwrap_or(\"\").trim();\n        let short: String = line.chars().take(80).collect();\n        if short.is_empty() {\n            format!(\"Thread de @{}\", first.author.handle)\n        } else {\n            short\n        }\n    }\n}\n\npub async fn unroll(input: &str) -> anyhow::Result<Thread> {\n    let id = super::post_id_from(input)\n        .ok_or_else(|| anyhow!(\"nao reconheci um post do X em: {}\", input))?;\n    match super::fx::thread(&id).await {\n        Ok((focal, posts, truncated)) => {\n            let posts = if posts.is_empty() {\n                vec![focal.clone()]\n            } else {\n                posts\n            };\n            Ok(Thread {\n                focal,\n                posts,\n                truncated,\n                source: \"fxtwitter\".into(),\n            })\n        }\n        Err(fx_err) => {\n            tracing::info!(\"[x] fxtwitter falhou ({}), tentando GraphQL\", fx_err);\n            unroll_graphql(&id)\n                .await","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/x/thread.rs#L18-L54","documentation":"unroll reconstructs an X thread and throws this error when `post_id_from` cannot extract a tweet ID from the input. The parser accepts a bare numeric ID or any URL containing `status(es)/<digits>` or `i/web/status/<digits>` (x.com or twitter.com). The unrecognized input is embedded in the message.","triggerScenarios":"Calling unroll with a non-numeric, non-status-URL string: a profile URL (https://x.com/nasa), a shortened t.co/syndication link without a status path, an ID containing letters or separators (spaces, commas from copy-paste), or an empty string.","commonSituations":"Pasting a profile or media-tab URL instead of a tweet link; passing a vxtwitter/fxtwitter-style URL variant whose path the regex does not cover; extracting the ID with wrong split (grabbing `photo/1` or trailing `?s=20` text); mobile share sheets adding extra text around the link.","solutions":["Pass either the bare tweet ID (all digits) or the full x.com/twitter.com status URL — strip surrounding text/whitespace before calling","Pre-validate with the same pattern the library uses (`(?:status(?:es)?|i/web/status)/(\\d+)`) and surface a friendly message on no-match","If handling alternate frontends (fixupx, vxtwitter), rewrite the host to x.com or extract the status path yourself before calling unroll"],"exampleFix":"// before\nunroll(shared_text).await?;\n// after\nlet re = regex::Regex::new(r\"(?:status(?:es)?|i/web/status)/(\\d+)\").unwrap();\nlet id: Option<String> = if shared_text.trim().chars().all(|c| c.is_ascii_digit()) && !shared_text.trim().is_empty() {\n    Some(shared_text.trim().to_string())\n} else {\n    re.captures(shared_text).map(|c| c[1].to_string())\n};\nlet id = id.ok_or_else(|| anyhow!(\"'{shared_text}' nao contem um ID de post do X\"))?;\nunroll(&id).await?;","handlingStrategy":"validation","validationCode":"fn extract_tweet_id(input: &str) -> Option<String> {\n    let s = input.trim();\n    if !s.is_empty() && s.chars().all(|c| c.is_ascii_digit()) {\n        return Some(s.to_string());\n    }\n    let re = regex::Regex::new(r#\"(?:status(?:es)?|i/web/status)/(\\d+)\"#).ok()?;\n    re.captures(s).map(|c| c[1].to_string())\n}\n// only call unroll when extract_tweet_id(input).is_some()","typeGuard":"fn is_tweet_ref(input: &str) -> bool {\n    let s = input.trim();\n    (!s.is_empty() && s.chars().all(|c| c.is_ascii_digit()))\n        || regex::Regex::new(r#\"(?:status(?:es)?|i/web/status)/\\d+\"#).map(|r| r.is_match(s)).unwrap_or(false)\n}","tryCatchPattern":"match unroll(input).await {\n    Err(e) if e.to_string().contains(\"nao reconheci um post\") => {\n        eprintln!(\"Cole o link do post (x.com/.../status/ID) ou o ID numerico\");\n    }\n    Err(e) => return Err(e),\n    Ok(thread) => thread,\n}","preventionTips":["Extract the numeric ID yourself (regex status/(\\d+)) and pass the bare ID","Clean text copied from mobile share sheets (extra words around the URL)","Rewrite alternate-frontend URLs (vxtwitter/fixupx) to x.com before calling","Never pass profile or media-tab URLs to unroll — they have no status path"],"tags":["validation","input-parsing","url","x"],"backgroundTag":"invalid-argument-format","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"}