{"record":{"id":"7776ae61c761359d","repo":"tonhowtf/omniget","slug":"nao-consegui-desfazer-o-save-de-http","errorCode":null,"errorMessage":"nao consegui desfazer o save de {} (HTTP {}): {}","messagePattern":"nao consegui desfazer o save de (.+?) \\(HTTP (.+?)\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pinterest/api.rs","lineNumber":1259,"sourceCode":"    pub async fn unsave(&self, pin_id: &str) -> anyhow::Result<()> {\n        let csrf = self.csrf.clone().ok_or_else(|| {\n            anyhow!(\"para desfazer saves informe os cookies da sua sessao (com csrftoken)\")\n        })?;\n        let data = json!({ \"options\": { \"id\": pin_id }, \"context\": {} }).to_string();\n        let req = self\n            .http\n            .post(format!(\"{}/resource/PinResource/delete/\", ROOT))\n            .header(\"X-CSRFToken\", csrf)\n            .header(\"Content-Type\", \"application/x-www-form-urlencoded\")\n            .form(&[(\"source_url\", format!(\"/pin/{}/\", pin_id)), (\"data\", data)]);\n        let resp = self.apply_cookie(req).send().await?;\n        let status = resp.status();\n        let body: Value = resp.json().await.unwrap_or(Value::Null);\n        if !status.is_success() || body[\"resource_response\"][\"status\"].as_str() != Some(\"success\") {\n            let msg = body[\"resource_response\"][\"error\"][\"message\"]\n                .as_str()\n                .unwrap_or(\"falhou\");\n            return Err(anyhow!(\n                \"nao consegui desfazer o save de {} (HTTP {}): {}\",\n                pin_id,\n                status,\n                msg\n            ));\n        }\n        Ok(())\n    }\n\n    /// Feed a partir de um alvo já resolvido (board precisa do id).\n    pub async fn feed_for(&self, target: &Target) -> anyhow::Result<(Feed, String)> {\n        match target {\n            Target::Board { user, slug } => {\n                let b = self.board(user, slug).await?;\n                Ok((\n                    Feed::Board {\n                        board_id: b.id.clone(),\n                        include_sections: true,","sourceCodeStart":1241,"sourceCodeEnd":1277,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pinterest/api.rs#L1241-L1277","documentation":"After POSTing to PinResource/delete, unsave() checks both the HTTP status and Pinterest's resource_response.status field. If the request failed or Pinterest reported status != \"success\", it raises this error embedding the pin id, HTTP status, and Pinterest's own error message (or \"falhou\" when absent). It wraps a server-side rejection of the delete/save-removal operation.","triggerScenarios":"Calling unsave(pin_id) when the pin is not saved by that account, the csrftoken is stale/mismatched with the session cookie, the session expired, or Pinterest rate-limits/blocks the resource delete call.","commonSituations":"Stale cookies after Pinterest rotated csrftoken; trying to unsave pins saved by another account; bulk unsave loops tripping rate limits; pin already removed so delete returns an error payload.","solutions":["Read the embedded Pinterest error message in the error text — it states the actual cause.","Refresh session cookies (and matching csrftoken) and retry.","Confirm the pin is actually in the target account's saved list before calling unsave.","Add delay between unsave calls in bulk operations to avoid rate limiting."],"exampleFix":"// before\napi.unsave(&pin_id).await?;\n// after\nif let Err(e) = api.unsave(&pin_id).await {\n    let msg = e.to_string();\n    if msg.contains(\"HTTP 429\") { sleep(Duration::from_secs(30)).await; api.unsave(&pin_id).await?; }\n    else { return Err(e); }\n}","handlingStrategy":"retry","validationCode":"// Confirm the pin is in the account's saved list before unsaving\nlet saved = api.user_boards(&me).await?; // or check saved-pin feed first","typeGuard":"null","tryCatchPattern":"for attempt in 0..3 {\n    match api.unsave(&pin_id).await {\n        Ok(()) => break,\n        Err(e) if e.to_string().contains(\"HTTP 429\") && attempt < 2 => sleep(30s).await,\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Read the Pinterest error message embedded in the error text","Refresh cookies/csrftoken as a pair","Throttle bulk unsave loops","Skip pins already removed instead of treating as fatal"],"tags":["pinterest","api-error","csrf","delete"],"backgroundTag":"api-error-response","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}