tonhowtf/omniget · error
Token sem signature
Error message
Token sem signature
What it means
Thrown in fetch_access_token when Twitch's clip playback access token JSON response contains no string field named "signature". The library requires both signature and value to construct an authenticated playback URL; without the signature the token is unusable, so it fails fast with this Portuguese message ("Token without signature").
Solutions
- Log the raw token_obj JSON to inspect what Twitch actually returned
- Check for a GraphQL "errors" array in the response before reading signature
- Verify the clip slug is valid and not removed/geo-blocked
- Update the GQL query/parsing to match Twitch's current schema
Example fix
// before
let signature = token_obj.get("signature").and_then(|v| v.as_str()).ok_or_else(|| anyhow!("Token sem signature"))?.to_string();
// after
let signature = token_obj.get("signature")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow!("Token sem signature; raw response: {}", token_obj))?;
if token_obj.get("errors").is_some() { anyhow::bail!("Twitch GQL error: {}", token_obj["errors"]); } Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: pre-check parsed token object
fn has_valid_token(obj: &serde_json::Value) -> bool {
obj.get("signature").and_then(|v| v.as_str()).is_some()
} Type guard
fn is_string_field(v: &serde_json::Value, key: &str) -> Option<&str> {
v.get(key).and_then(|x| x.as_str())
} Try / catch
match fetch_access_token(slug).await {
Ok(token) => token,
Err(e) if e.to_string().contains("Token sem signature") => {
// inspect raw response / retry / fallback
return Err(MediaError::Upstream(format!("twitch token unusable: {e}")));
}
Err(e) => return Err(e.into()),
} Prevention
- Log the raw GQL response once during development to know the real schema
- Check for a GraphQL "errors" array before parsing fields
- Alert when this error rate spikes — it signals a Twitch schema change
- Keep the GQL query hash/operation updated with the web client
When it happens
Trigger: Twitch's GQL PlaybackAccessToken query succeeds but the playbackAccessToken object lacks a string "signature" field — e.g. the API returned an error object, null fields, or changed its response schema.
Common situations: Twitch changes its GraphQL response shape; clip is geo-blocked or removed and Twitch returns partial JSON; response is actually an errors array instead of data.clip.playbackAccessToken content.
Related errors
- Token sem value
- Track sem soundcloud_id
- SoundCloud nao retornou URL
- Spotify SDK device not ready
- Track sem metadata pra resolver no YouTube
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/7534d0f7cf866072.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/platforms/twitch.rs:237
if !response.status().is_success() {
return Err(anyhow!(
"Twitch GQL token retornou HTTP {}",
response.status()
));
}
let json: serde_json::Value = response.json().await?;
let token_obj = json
.as_array()
.and_then(|arr| arr.first())
.and_then(|r| r.pointer("/data/clip/playbackAccessToken"))
.ok_or_else(|| anyhow!("Access token not available for clip: {}", slug))?;
let signature = token_obj
.get("signature")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow!("Token sem signature"))?
.to_string();
let value = token_obj
.get("value")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow!("Token sem value"))?
.to_string();
Ok(AccessToken { signature, value })
}
fn build_authenticated_url(source_url: &str, token: &AccessToken) -> String {
format!(
"{}?sig={}&token={}",
source_url,
urlencoding::encode(&token.signature),
urlencoding::encode(&token.value),
)View on GitHub (pinned to 8600b91f42)