tonhowtf/omniget · error
para desfazer saves informe os cookies da sua sessao (com…
Error message
para desfazer saves informe os cookies da sua sessao (com csrftoken)
What it means
unsave() performs an authenticated POST to PinResource/delete, which requires the csrftoken from the user's Pinterest session cookies. The client's stored `csrf` Option is None, so the call fails fast with this message before making any network request. It is a precondition error: write operations simply cannot proceed without session credentials.
Solutions
- Re-create the client with full session cookies copied from a logged-in browser session (must include csrftoken).
- Check the cookie string actually contains `csrftoken=...` before constructing the client.
- Re-export cookies if the Pinterest session expired and csrftoken was rotated.
- Gate the unsave feature in UI code behind a check that cookies are configured.
Example fix
// before
let api = PinterestApi::new(None); // no cookies
api.unsave(&pin_id).await?;
// after
let cookies = env::var("PINTEREST_COOKIES")?;
anyhow::ensure!(cookies.contains("csrftoken="), "cookies must include csrftoken");
let api = PinterestApi::new(Some(cookies));
api.unsave(&pin_id).await?; Defensive patterns
Strategy: validation
Validate before calling
fn cookies_have_csrf(cookies: &str) -> bool {
cookies.split(';').any(|c| c.trim().starts_with("csrftoken="))
} Type guard
null
Try / catch
match api.unsave(&pin_id).await {
Err(e) if e.to_string().contains("csrftoken") => {
prompt_user("Paste cookies including csrftoken");
}
other => other?,
} Prevention
- Check for csrftoken= in the cookie string before building the client
- Re-export cookies after Pinterest rotates the token
- Gate write features in UI behind a cookies-configured check
- Never build the client from a partial cookie export
When it happens
Trigger: Calling PinterestApi::unsave(pin_id) on a client built without cookies, or with cookies that lack the csrftoken entry.
Common situations: Users configured the app for read-only scraping (anonymous client) and then try a write action; cookies pasted from a browser export missing csrftoken; cookies cleared on app restart.
Related errors
- a sessão do Goodreads não está válida: capture os cookies…
- não achei o token anti-CSRF do Goodreads; recapture os…
- sem sessão do Goodreads: capture os cookies de…
- nao consegui desfazer o save de
- os favoritos e os curtidos só saem com a sua sessão…
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/d4fe46b5737dc130.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/pinterest/api.rs:1243
break;
}
let r = self.http.get(&loc).send().await?;
match r
.headers()
.get(reqwest::header::LOCATION)
.and_then(|v| v.to_str().ok())
{
Some(l) => loc = l.to_string(),
None => break,
}
}
Ok(loc.split("/sent/").next().unwrap_or(&loc).to_string())
}
/// Desfaz o save de um pin seu (exige cookies com `csrftoken`).
pub async fn unsave(&self, pin_id: &str) -> anyhow::Result<()> {
let csrf = self.csrf.clone().ok_or_else(|| {
anyhow!("para desfazer saves informe os cookies da sua sessao (com csrftoken)")
})?;
let data = json!({ "options": { "id": pin_id }, "context": {} }).to_string();
let req = self
.http
.post(format!("{}/resource/PinResource/delete/", ROOT))
.header("X-CSRFToken", csrf)
.header("Content-Type", "application/x-www-form-urlencoded")
.form(&[("source_url", format!("/pin/{}/", pin_id)), ("data", data)]);
let resp = self.apply_cookie(req).send().await?;
let status = resp.status();
let body: Value = resp.json().await.unwrap_or(Value::Null);
if !status.is_success() || body["resource_response"]["status"].as_str() != Some("success") {
let msg = body["resource_response"]["error"]["message"]
.as_str()
.unwrap_or("falhou");
return Err(anyhow!(
"nao consegui desfazer o save de {} (HTTP {}): {}",
pin_id,View on GitHub (pinned to 8600b91f42)