You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of epic #987 — Memory & CPU full-app performance audit 2026-08.
Important
For the implementing agent: validate before implementing.
This issue was filed from a static audit on 2026-08-07 (main @ e4c9c90). Line numbers may have drifted.
First, CONFIRM the issue is still valid on current main: read the referenced files, verify the described behavior still exists in code, and check that no later commit already fixed it.
If it is no longer valid, comment your evidence and close the issue — do not implement.
If valid, implement following the conventions in CLAUDE.md/AGENTS.md: surgical change, tests included, run the Verify commands (pnpm lint, pnpm typecheck, relevant pnpm test:*, pnpm docs:impact) before opening a PR that references this issue.
Problem. The guarded helper broadcastToAllWindows (apps/desktop/src/main/lib/window-broadcast.ts:12-18, checks isDestroyed() on both window and webContents) exists precisely because an unguarded throw inside a DB transaction rolled back applied sync items. Despite the migration (#935, commits c086ca2/430904df7/39b56e73c), 39 hand-rolled BrowserWindow.getAllWindows().forEach(win => win.webContents.send(...)) loops remain. Highest-risk sites: sync/item-handlers/settings-handler.ts:163-194 (inside sync apply → rollback), sync/token-manager.ts:107-109 (SESSION_EXPIRED, fires during teardown when windows are dying), ipc/sync-core-handlers.ts:177. Full list also covers vault/index.ts:200,210,220,247, vault/notes-io.ts:52, vault/watcher.ts:117, vault/rename-tracker.ts:80, sync/crdt-writeback.ts:151, sync/linking-service.ts:545, 7 sites in ipc/settings-handlers.ts, 4 in ipc/sync-attachment-handlers.ts, plus journal/bookmarks/tags/canvas/saved-filters/calendar/locale/ai-inline/auth-device/auth-oauth handlers, import/import-context.ts:41, inbox/review-notification.ts:24, lib/reminders.ts:281.
Trigger. Any window destroyed concurrently with an emit — near-certain over a full-day multi-window session.
Suggested fix. Mechanically replace all production loops with broadcastToAllWindows. Add an ESLint no-restricted-syntax rule banning webContents.send inside getAllWindows() loops so it cannot regress a fourth time.
Verification. Grep returns zero unguarded loops outside test hooks; lint rule fails on a synthetic violation.
Part of epic #987 — Memory & CPU full-app performance audit 2026-08.
Important
For the implementing agent: validate before implementing.
This issue was filed from a static audit on 2026-08-07 (
main@ e4c9c90). Line numbers may have drifted.main: read the referenced files, verify the described behavior still exists in code, and check that no later commit already fixed it.CLAUDE.md/AGENTS.md: surgical change, tests included, run the Verify commands (pnpm lint,pnpm typecheck, relevantpnpm test:*,pnpm docs:impact) before opening a PR that references this issue.Problem. The guarded helper
broadcastToAllWindows(apps/desktop/src/main/lib/window-broadcast.ts:12-18, checksisDestroyed()on both window and webContents) exists precisely because an unguarded throw inside a DB transaction rolled back applied sync items. Despite the migration (#935, commits c086ca2/430904df7/39b56e73c), 39 hand-rolledBrowserWindow.getAllWindows().forEach(win => win.webContents.send(...))loops remain. Highest-risk sites:sync/item-handlers/settings-handler.ts:163-194(inside sync apply → rollback),sync/token-manager.ts:107-109(SESSION_EXPIRED, fires during teardown when windows are dying),ipc/sync-core-handlers.ts:177. Full list also coversvault/index.ts:200,210,220,247,vault/notes-io.ts:52,vault/watcher.ts:117,vault/rename-tracker.ts:80,sync/crdt-writeback.ts:151,sync/linking-service.ts:545, 7 sites inipc/settings-handlers.ts, 4 inipc/sync-attachment-handlers.ts, plusjournal/bookmarks/tags/canvas/saved-filters/calendar/locale/ai-inline/auth-device/auth-oauth handlers,import/import-context.ts:41,inbox/review-notification.ts:24,lib/reminders.ts:281.Trigger. Any window destroyed concurrently with an emit — near-certain over a full-day multi-window session.
Suggested fix. Mechanically replace all production loops with
broadcastToAllWindows. Add an ESLintno-restricted-syntaxrule banningwebContents.sendinsidegetAllWindows()loops so it cannot regress a fourth time.Verification. Grep returns zero unguarded loops outside test hooks; lint rule fails on a synthetic violation.