tonhowtf/omniget · error
nao reconheci um perfil do X em
Error message
nao reconheci um perfil do X em: {} What it means
download_profile parses the user input into an X handle with `handle_from` and throws this error when parsing fails. `handle_from` accepts `@name`, bare `name` (1-15 [A-Za-z0-9_]), or an x.com/twitter.com profile URL, rejecting reserved path segments like `i`, `home`, `search`. The message embeds the raw unrecognized input.
Solutions
- Pass a valid handle: `@nasa`, `nasa`, or `https://x.com/nasa` — trim whitespace and surrounding punctuation before calling
- If input may be a tweet URL, route it to thread/post functions instead, or extract the screen name via handle_from first and show a validation message on None
- Reject reserved route names (i, home, search, ...) in your own UI validation before calling
Example fix
// before
download_profile(user_input.trim(), 100, true, false, progress).await?;
// after
let input = user_input.trim().trim_start_matches('@');
anyhow::ensure!(!input.is_empty() && input.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') && input.len() <= 15,
"'{input}' nao parece um handle do X (use @nome, nome ou https://x.com/nome)");
download_profile(input, 100, true, false, progress).await?; Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_x_handle(input: &str) -> bool {
let s = input.trim().trim_start_matches('@');
!s.is_empty() && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') && s.chars().count() <= 15
}
// call download_profile only if is_valid_x_handle(user_input) or input is a profile URL on x.com/twitter.com Type guard
fn as_x_handle(input: &str) -> Option<String> {
let s = input.trim().trim_start_matches('@');
(!s.is_empty()
&& s.chars().count() <= 15
&& s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_'))
.then(|| s.to_string())
} Try / catch
match download_profile(input, limit, photos, videos, progress).await {
Err(e) if e.to_string().contains("nao reconheci um perfil") => {
eprintln!("Entrada invalida: use @handle, handle ou https://x.com/handle");
}
Err(e) => return Err(e),
Ok(res) => res,
} Prevention
- Trim whitespace, '@' prefix and surrounding punctuation from user input before calling
- Route tweet/status URLs to post/thread functions, not profile functions
- Reject reserved route names (i, home, search, explore, ...) in your own validation
- Enforce X's 1-15 char [A-Za-z0-9_] handle rule in the UI before invoking the tool
When it happens
Trigger: Calling download_profile with input that is empty after trimming '@', longer than 15 chars, contains characters outside [A-Za-z0-9_], is a status URL (`/status/123`) instead of a profile URL, or a URL pointing at a reserved path (e.g. https://x.com/search?q=...).
Common situations: Pasting a tweet link instead of a profile link; input containing full display names with spaces (`Elon Musk`); handles with trailing punctuation from copy/paste; locale input from UI passing raw text like 'my profile'; handles longer than Twitter's 15-char limit (renamed accounts).
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- nao reconheci um perfil do X em
- nao reconheci um post do X em
- a API oficial so aceita URLs publicas (https://…) para os…
- cole a URL de um .m3u8 ou .mpd
- cole um link do slideshare.net
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/8d6261c83bcefc58.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/x/media.rs:156
}
let bytes = resp.bytes().await?;
let part = path.with_extension("part");
tokio::fs::write(&part, &bytes).await?;
tokio::fs::rename(&part, path).await?;
Ok(())
}
/// Todas as midias publicas de um perfil (aba Midia), ate `limit` posts.
pub async fn download_profile(
input: &str,
dest: &str,
limit: usize,
photos: bool,
videos: bool,
progress: ProgressFn,
) -> anyhow::Result<MediaResult> {
let handle = super::handle_from(input)
.ok_or_else(|| anyhow!("nao reconheci um perfil do X em: {}", input))?;
let job = format!("x-media:{}", handle.to_ascii_lowercase());
super::clear_cancel(&job);
let mut posts: Vec<XPost> = Vec::new();
let mut cursor: Option<String> = None;
let limit = if limit == 0 { 5000 } else { limit };
for _ in 0..200 {
if super::cancelled(&job) {
break;
}
super::report(&progress, &job, "listing", posts.len() as u64, None, None);
let page = super::fx::profile_media(&handle, cursor.as_deref()).await?;
if page.items.is_empty() {
break;
}
posts.extend(page.items.into_iter().filter(|p| !p.media.is_empty()));
if posts.len() >= limit || page.cursor.is_none() {
break;
}View on GitHub (pinned to 8600b91f42)