[SP 18.13.1 / macOS] Initial sync race on startup: last binding fails when multiple bindings are configured #18

Closed
opened 2026-07-06 09:47:23 +02:00 by fpindado · 1 comment
Owner

Environment: Super Productivity v18.13.1 (macOS, Apple Silicon). Not reproducible on 18.9.1D.

Summary
On app startup with multiple bindings (3 in my setup), the initial sync of the last binding in config order (confirmed: Laboral Kutxa) fails with a snack:

Sync.md: Initial sync failed for '…'. Plugin is still active.

It is recoverable — pressing Sync Now afterwards syncs the failed binding fine. It only happens at startup.

Steps to reproduce

  1. Configure 3+ bindings.
  2. Restart Super Productivity.
  3. On startup, the last binding shows the "Initial sync failed" snack.

Expected
Every binding's initial sync completes on startup, regardless of how many bindings are configured.

Root cause
On startup, initSyncRegistry launched performInitialSync for every binding in parallel (fire-and-forget). SP 18.13.1 starts plugins faster (no consent dialog after the first grant), so the near-simultaneous initial syncs race and SP cannot process them all at once → the last one fails. On 18.9.1D the slower activation path masked this.

Fix

  • Serialize the initial syncs in sync-manager.ts — create the sessions synchronously, then run performInitialSync sequentially (await per binding) instead of launching them all at once.
  • Wait for plugin.onReady() in background.ts before loading config / initial sync (feature-detected, with a fallback timeout — the recommended 18.13.1 lifecycle).

Introduced by the faster no-dialog startup in SP 18.13.1.

**Environment:** Super Productivity **v18.13.1** (macOS, Apple Silicon). Not reproducible on 18.9.1D. **Summary** On app startup with **multiple bindings** (3 in my setup), the initial sync of the **last binding in config order** (confirmed: *Laboral Kutxa*) fails with a snack: > Sync.md: Initial sync failed for '…'. Plugin is still active. It is **recoverable** — pressing **Sync Now** afterwards syncs the failed binding fine. It only happens **at startup**. **Steps to reproduce** 1. Configure 3+ bindings. 2. Restart Super Productivity. 3. On startup, the last binding shows the "Initial sync failed" snack. **Expected** Every binding's initial sync completes on startup, regardless of how many bindings are configured. **Root cause** On startup, `initSyncRegistry` launched `performInitialSync` for every binding **in parallel** (fire-and-forget). SP 18.13.1 starts plugins faster (no consent dialog after the first grant), so the near-simultaneous initial syncs race and SP cannot process them all at once → the last one fails. On 18.9.1D the slower activation path masked this. **Fix** - Serialize the initial syncs in `sync-manager.ts` — create the sessions synchronously, then run `performInitialSync` **sequentially** (`await` per binding) instead of launching them all at once. - Wait for `plugin.onReady()` in `background.ts` before loading config / initial sync (feature-detected, with a fallback timeout — the recommended 18.13.1 lifecycle). Introduced by the faster no-dialog startup in SP 18.13.1.
Author
Owner

Fixed in commit 5161a1d.

Root cause: on startup, initSyncRegistry launched performInitialSync for every binding in parallel (fire-and-forget). SP 18.13.1's faster, no-dialog startup made the near-simultaneous initial syncs race, so the last binding failed with the recoverable "Initial sync failed" snack. 18.9.1D's slower activation path had masked it.

Fix:

  • sync-manager.ts — sessions are now created synchronously, then their initial syncs run sequentially (runInitialSyncsSequentially, await performInitialSync per binding) instead of firing all at once.
  • background.ts — the plugin now waits for plugin.onReady() before loading config / running the initial sync (feature-detected, with a 3 s fallback, since onReady isn't in the current plugin-API types).

Verified on SP 18.13.1 (macOS M2): on startup with 3 bindings the "Initial sync failed" snack no longer appears and all bindings sync correctly.

Closing as fixed.

Fixed in commit 5161a1d. Root cause: on startup, initSyncRegistry launched performInitialSync for every binding in parallel (fire-and-forget). SP 18.13.1's faster, no-dialog startup made the near-simultaneous initial syncs race, so the last binding failed with the recoverable "Initial sync failed" snack. 18.9.1D's slower activation path had masked it. Fix: - sync-manager.ts — sessions are now created synchronously, then their initial syncs run sequentially (runInitialSyncsSequentially, await performInitialSync per binding) instead of firing all at once. - background.ts — the plugin now waits for plugin.onReady() before loading config / running the initial sync (feature-detected, with a 3 s fallback, since onReady isn't in the current plugin-API types). Verified on SP 18.13.1 (macOS M2): on startup with 3 bindings the "Initial sync failed" snack no longer appears and all bindings sync correctly. Closing as fixed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
fpindado/sync-md-multi#18
No description provided.