tonhowtf/omniget · error · anyhow
o Trakt não devolveu o token
Error message
o Trakt não devolveu o token
What it means
Thrown by save_token when the token JSON returned by Trakt has an empty or missing access_token. The token cannot be persisted or used, so the connection attempt fails. Called from wait_for_token's poll success and refresh_if_needed.
Solutions
- Log the full token response body to see what Trakt actually returned
- Check for proxy/VPN interference on api.trakt.tv
- Restart the device flow (device_code + wait_for_token) to obtain a fresh token
- If the response shape changed, update the field extraction in save_token
Example fix
// before
let v: Value = r.json().await?;
save_token(&v)?;
// after
let v: Value = r.json().await?;
tracing::debug!("token keys: {:?}", v.as_object().map(|o| o.keys().collect::<Vec<_>>()));
save_token(&v)?; Defensive patterns
Strategy: try-catch
Validate before calling
if body.get("access_token").and_then(|x| x.as_str()).map_or(true, str::is_empty) {
// do not call save_token; log body and surface a reconnect error
} Type guard
fn has_access_token(v: &serde_json::Value) -> bool {
v.get("access_token").and_then(|x| x.as_str()).map_or(false, |s| !s.is_empty())
} Try / catch
match connect_flow().await {
Err(e) if e.to_string().contains("não devolveu o token") => {
// inspect raw response, check proxy/VPN, restart device flow
}
other => other?,
} Prevention
- Validate token payload fields before persisting
- Disable interfering proxies/VPNs for api.trakt.tv
- Persist tokens atomically right after receipt
When it happens
Trigger: Poll success or refresh response body lacks a non-empty access_token string — e.g. Trakt returned an error-shaped JSON, or the response was truncated/mangled by a proxy.
Common situations: Proxies/VPN returning 200 with an HTML or error body; Trakt API behavioral changes; tests/mocks with incomplete token payloads; a refresh call that actually failed but returned 200.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- o Trakt não devolveu o código do dispositivo
- a autorização do Trakt expirou de vez. Conecte a conta de…
- conecte a conta do Trakt primeiro (o código aparece aqui e…
- informe o client_id da sua app do Trakt
- informe primeiro o client_id da sua app do Trakt
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/c19bf1a93a022b27.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/lists/trakt.rs:354
username: username.clone(),
message: format!("conectado como {}", username),
});
}
Poll::SlowDown => interval += Duration::from_secs(dc.interval.max(1)),
Poll::Pending => {}
other => return Err(anyhow!("{}", other.message())),
}
}
}
fn save_token(v: &Value) -> Result<String> {
let access = v
.get("access_token")
.and_then(|x| x.as_str())
.unwrap_or_default()
.to_string();
if access.is_empty() {
return Err(anyhow!("o Trakt não devolveu o token"));
}
let refresh = v
.get("refresh_token")
.and_then(|x| x.as_str())
.unwrap_or_default()
.to_string();
let created = v.get("created_at").and_then(|x| x.as_i64()).unwrap_or(0);
let expires = v.get("expires_in").and_then(|x| x.as_i64()).unwrap_or(0);
let base = if created > 0 {
created
} else {
chrono::Utc::now().timestamp()
};
let _g = LOCK.lock().unwrap_or_else(|e| e.into_inner());
let mut c = load();
c.access_token = access;
c.refresh_token = refresh;
c.expires_at = base + expires;View on GitHub (pinned to 8600b91f42)