Conversation
MAILSPRING-CLIENT-T has kept firing at the same rate (342 users, 1163 events) since PR #2727 landed in this exact release (1.21.1-ae68e881). That PR's description described a retry-with-delay fix for the transaction-ordering race between the SyncbackDraftTask status update and the draft row's own SQLite write, but the actual diff only added diagnostics and a TaskQueue leak fix — the retry was never implemented. waitForPerformLocal() resolves as soon as the task leaves the 'local' status, including when the sync engine cancels it, which can race ahead of the draft row commit. Retry the DatabaseStore.findBy lookup once after a short delay to absorb that race before surfacing the error dialog and reporting to Sentry. Fixes MAILSPRING-CLIENT-T Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SNN84RVmDKgi4UCtiGSKhP
Contributor
|
Important Indent Zero has shut down and no longer reviews pull requests.
Step 4 is only needed for pull requests that were already open when you switched. After that, Indent reviews new pull requests on its own. To stop this notice, turn PR reviews off in Indent Zero. |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What I observed in Sentry
MAILSPRING-CLIENT-T is the highest-impact unresolved issue on release
1.21.1-ae68e881(342 users total, 1163 events, still firing today). It'sError: Could not find draft after finalizing session for sending., thrown fromDraftStore._onUnexpectedNotFoundDuringSendinapp/src/flux/stores/draft-store.ts.This exact issue was the subject of #2727, merged into
masterat commitae68e881— the same commit this release build was cut from. That PR's description proposed three fixes, including "retry the post-commit database query once with a 150ms delay" to absorb a transaction-ordering race. But diffing the actual PR only shows two of the three changes landing: the diagnosticextrapayload and aTaskQueuearray-leak fix. The retry logic described in the PR body was never actually implemented in the diff. That explains why the issue's event rate is unchanged after that "fix" shipped — nothing about the retrieval logic itself changed.Root cause
DraftStore._onSendDraftawaitssession.changes.commit(), which callsDraftEditingSession.changeSetCommit(). That queues aSyncbackDraftTaskand awaitsTaskQueue.waitForPerformLocal(task).waitForPerformLocalresolves as soon as the task's status leaves'local'—Task.hasRunLocally()returnstruefor any non-'local'status, including'cancelled'(app/src/flux/tasks/task.ts:56).The sync engine (C++) can commit the task-status transition and the draft row write in separate SQLite transactions. If the status-update transaction lands first,
waitForPerformLocalresolves and_onSendDraftimmediately queriesDatabaseStore.findBy({ headerMessageId, draft: true })— which can returnnulleven though the draft row write is about to land a moment later. The result: a real user's draft that saved successfully throws a scary "could not be found" dialog and gets reported to Sentry.Fix
In
app/src/flux/stores/draft-store.ts, when the post-commitDatabaseStore.findBylookup returnsnull, wait 150ms and retry the same query once before giving up and calling_onUnexpectedNotFoundDuringSend. This is long enough to absorb the transaction-ordering race (the sync engine's own change-notification throttle is itself 150ms) while being imperceptible on the happy path, where it's never hit. I also record whether the retry succeeded (diagnostics.foundOnRetry) so if the issue keeps recurring after this, Sentry will make it obvious whether the race is what's left or something else is going on.Test plan
npm run lintpasses on the changed filetsc --noEmitshows no new errors introduced by this change (pre-existing errors in the tree are from unrelated missing optional native/type dependencies in this sandboxed environment)SyncbackDraftTask) and verify the retry resolves it without surfacing the error dialogFixes MAILSPRING-CLIENT-T
🤖 Generated with Claude Code
https://claude.ai/code/session_01SNN84RVmDKgi4UCtiGSKhP
Generated by Claude Code