{"record":{"id":"f164cb8ac18b7554","repo":"tonhowtf/omniget","slug":"agendamento-sem-token-da-api","errorCode":null,"errorMessage":"agendamento sem token da API","messagePattern":"agendamento sem token da API","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/commands/tools/instagram.rs","lineNumber":788,"sourceCode":"pub fn start_scheduler(app: tauri::AppHandle) {\n    if SCHEDULER.set(()).is_err() {\n        return;\n    }\n    tauri::async_runtime::spawn(async move {\n        loop {\n            tokio::time::sleep(std::time::Duration::from_secs(30)).await;\n            let now = chrono::Utc::now().timestamp();\n            let Some(mut post) = publish::schedule_due(now) else {\n                continue;\n            };\n            post.status = \"running\".into();\n            let _ = publish::schedule_update(&post);\n            let job = format!(\"schedule:{}\", post.id);\n            let p = progress(&app);\n            let outcome = if post.mode == \"graph\" {\n                match &post.graph {\n                    Some(auth) => publish::publish_graph(auth, &post.request, &p, &job).await,\n                    None => Err(anyhow::anyhow!(\"agendamento sem token da API\")),\n                }\n            } else {\n                match load_client(post.account_slug.as_deref()) {\n                    Ok(client) => publish::publish_web(&client, &post.request, &p, &job).await,\n                    Err(e) => Err(anyhow::anyhow!(e)),\n                }\n            };\n            match outcome {\n                Ok(r) => {\n                    post.status = \"done\".into();\n                    post.result = Some(r);\n                }\n                Err(e) => {\n                    post.status = \"failed\".into();\n                    post.error = Some(e.to_string());\n                }\n            }\n            let _ = publish::schedule_update(&post);","sourceCodeStart":770,"sourceCodeEnd":806,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/commands/tools/instagram.rs#L770-L806","documentation":"In the Instagram scheduler loop, a post with mode == \"graph\" (publish via the official Instagram Graph API) must carry its stored Graph API auth/token in post.graph. When that field is None the job cannot be published and fails with 'agendamento sem token da API' ('scheduling without API token').","triggerScenarios":"A scheduled Instagram post row was created with mode=\"graph\" but post.graph is null — the account was never connected via the Graph API flow, the token was cleared/expired and removed, or the post was edited to graph mode without supplying credentials.","commonSituations":"User switched scheduling mode to Graph API without completing the Facebook/Instagram OAuth connection; token revoked in the Meta developer console; database row created by an older version that did not persist graph auth; token expiration cleanup job nulling post.graph.","solutions":["Reconnect the Instagram account via the Graph API OAuth flow so a token is stored, then re-save the post.","Change the post's mode from \"graph\" to web (app-API) publishing if Graph API credentials are unavailable.","Check that token storage isn't clearing post.graph on refresh/expiry — persist a refreshed token instead of nulling the field.","Add validation when creating/updating posts: reject mode=\"graph\" without graph auth so the bad row never reaches the scheduler.","Inspect the post row (post.id in job 'schedule:<id>') to confirm graph is null before re-authenticating."],"exampleFix":"// before\n// post saved with mode=\"graph\" and no token, fails at schedule time\napi.addPost({ mode: \"graph\", request });\n\n// after\nconst auth = await getGraphAuth(accountSlug);\nif (!auth) throw new Error(\"connect Instagram via Graph API before scheduling\");\napi.addPost({ mode: \"graph\", graph: auth, request });","handlingStrategy":"validation","validationCode":"function assertGraphPost(post) {\n  if (post.mode === 'graph' && !post.graph) {\n    throw new Error(`post ${post.id}: mode=graph requires a Graph API token; reconnect the account`);\n  }\n}\nassertGraphPost(post); // call before saving/scheduling","typeGuard":"function hasGraphAuth(post) {\n  return post.mode !== 'graph' || (post.graph != null && typeof post.graph === 'object');\n}","tryCatchPattern":null,"preventionTips":["Require OAuth completion before allowing mode=graph on a post","Refresh and persist Graph tokens instead of nulling them on expiry","Validate post rows at creation/edit time, not only at schedule time","Surface scheduler failures per job id so users know which post needs re-auth"],"tags":["instagram","scheduler","missing-credentials","graph-api"],"backgroundTag":"missing-credentials","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"}