From 36a5025198171887bd03b01d7ddfea8847012f3f Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Fri, 6 Mar 2026 15:53:43 -0500 Subject: [PATCH] fix(gtasks): prevent concurrent push/pull from racing on the store Problem: `push` and `pull` both run via `oauth.async`, so issuing them back-to-back starts two coroutines that interleave at every curl yield. Both snapshot `build_id_index` before either has mutated the store, which can cause push to create a remote task that pull would have recognized as already linked, producing duplicates on Google. Solution: guard `with_token` with a module-level `_in_flight` flag set before `oauth.async` is called so no second operation can start during a token-refresh yield. A `pcall` around the callback guarantees the flag is always cleared, even on an unexpected error. --- lua/pending/sync/gtasks.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lua/pending/sync/gtasks.lua b/lua/pending/sync/gtasks.lua index a2a6da0..8b918c2 100644 --- a/lua/pending/sync/gtasks.lua +++ b/lua/pending/sync/gtasks.lua @@ -436,15 +436,27 @@ local function sync_setup(access_token) return tasklists, s, now_ts end +local _in_flight = false + ---@param callback fun(access_token: string): nil local function with_token(callback) + if _in_flight then + log.warn('gtasks: operation in progress — please wait') + return + end + _in_flight = true oauth.async(function() local token = oauth.google_client:get_access_token() if not token then + _in_flight = false log.warn('not authenticated — run :Pending auth') return end - callback(token) + local ok, err = pcall(callback, token) + _in_flight = false + if not ok then + log.error('gtasks: ' .. tostring(err)) + end end) end