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

  1. Log the full token response body to see what Trakt actually returned
  2. Check for proxy/VPN interference on api.trakt.tv
  3. Restart the device flow (device_code + wait_for_token) to obtain a fresh token
  4. 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

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


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)