microsoft / microsoft/monaco-editor
[Bug] Safari: `installWebKitWriteTextWorkaround` leaks an unhandled `Canceled: Canceled` rejection on every click/keydown
@sbatten is already working on this.
Since Aug 21, 2026.
- Dominant language
- JavaScript
- Stars
- 46.8k
- Forks
- 4.1k
- Avg merge
- 17h 58m
- Merged PRs (30d)
- 1
Description
Reproducible in vscode.dev or in VS Code Desktop?
Not applicable — the code path only runs on Safari/WebKit (if (isSafari || isWebkitWebView)), so it cannot occur in Electron, and vscode.dev would need to be opened in Safari specifically.
Description
BrowserClipboardService.installWebKitWriteTextWorkaround produces an unhandled promise rejection that reaches window.onunhandledrejection, reported by error trackers as:
Canceled: Canceled
at DeferredPromise.cancel (vs/base/common/async.js)
at handler (vs/platform/clipboard/browser/clipboardService.js)
Cause
The workaround installs a click and keydown listener that, on every event, creates a DeferredPromise and cancels the previous one:
const handler = () => {
const currentWritePromise = new DeferredPromise();
// Cancel the previous promise since we just created a new one in response to this new event
if (this.webKitPendingClipboardWritePromise && !this.webKitPendingClipboardWritePromise.isSettled) {
this.webKitPendingClipboardWritePromise.cancel();
}
this.webKitPendingClipboardWritePromise = currentWritePromise;
getActiveWindow().navigator.clipboard.write([new ClipboardItem({
'text/plain': currentWritePromise.p,
})]).catch(async (err) => { ... });
};
DeferredPromise.cancel() rejects .p with a CancellationError. The only consumer of .p is the ClipboardItem constructor, which does not attach a rejection handler to it, so nothing ever observes that rejection. The .catch(...) attached to navigator.clipboard.write(...) handles a different promise — the write's own — and does not mark .p as handled.
The cancellation itself is intended behaviour, so this is pure noise: nothing is broken when it fires, and clipboard writes keep working. But because a click or keydown anywhere in the container triggers it, it fires constantly for Safari users and drowns real errors in telemetry.
Suggested fix
Observe the rejection where the deferred is created, leaving the promise handed to ClipboardItem (and the isRejected check the surrounding catch relies on) untouched:
const currentWritePromise = new DeferredPromise();
+// `ClipboardItem` does not attach a rejection handler to the promise it is given, so the
+// cancellation below would surface as an unhandled rejection on the window.
+currentWritePromise.p.catch(() => { });
// Cancel the previous promise since we just created a new one in response to this new event
if (this.webKitPendingClipboardWritePromise && !this.webKitPendingClipboardWritePromise.isSettled) {
this.webKitPendingClipboardWritePromise.cancel();
}
Environment
monaco-editor-core0.52.2; the code is unchanged in 0.56.0 and inmicrosoft/vscodemain- Safari 26.6, macOS
Possibly the same root cause
Several open reports describe Canceled: Canceled unhandled rejections triggered by clipboard interaction, none of which names this code path: #4389 (holding Cmd+V), #4776 (rapid pasting). #4389 is marked "not reproducible in vscode.dev or VS Code Desktop", which is consistent with a Safari-only path.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.