HomeMethodClipboard failure ladder

Copy does nothing: finding the clipboard layer that fails silently

Clipboard bugs are almost never exceptions. The write resolves, the toast appears, and the target still pastes yesterday's text — because between your function call and the paste there are five independent gates, and three of them fail quietly. This is the failure half of a clipboard bridge. The success path, how a host channel reaches a system writer, is documented by the project's own case study, which we are not affiliated with.

Independent guide. Behaviour and failure modes, reconstructed from public docs and a published trace. Not official documentation for REA or for any app named here. This page does not read another application's clipboard, and it does not help collect pasteboard data.

The five-gate ladder

Test top-down. Every rung has an observable that is different from its neighbour.

#GateWhat it really looks likeCheck in one line
1Secure contextnavigator.clipboard is undefined — no error, no promise, nothing to catchisSecureContext is false on plain HTTP and on LAN-IP dev origins
2User activationWrite rejected with NotAllowedError; reads pop a menu 1 s too late for your test to noticeCalled from setTimeout, an async continuation, or an observer callback? Activation is gone
3Permission / browser policyChrome asks once then remembers; Firefox and Safari show an ephemeral Paste menu instead — and never grant the permission your code waits forAny branch gated on clipboard-write permission state hangs there
4Frame policySilent deny inside an embed: same code works top-level, fails in the iframe, empty consoleChromium needs clipboard-read and clipboard-write allowed on the frame
5Host / IPCEverything above passes, the promise resolves, and the paste is still wrong — the drop happened after the browserSender check, channel name, format mismatch, or a stale private payload

Where the silent drops live. Gates 1, 3 and 5. Gates 1 and 3 produce no exception at all, and gate 5 is a host-side decision your JavaScript cannot observe. Most "clipboard is broken" reports are one of those three, and all three look identical from the UI.

Gate 2 is the one people blame the API for

MDN's security section separates read from write. A read is specified to need recent transient user activation plus the user actually acting on a paste affordance — though in practice browsers often allow reads that do not satisfy those requirements, and impose other requirements instead. A write expects the clipboard-write permission, and the browser may also require transient user activation.

Gates 1–4Environment only

Nothing here reads your clipboard. It only reports what the environment permits.

Gate 1

Secure context

checked on click

Gate 2

Activation

checked on click

Gate 3

Permissions

per browser — see the table above

Gate 4

Frame

checked on click

Press Check now. Nothing here reads or writes the clipboard.

// press Check now — results are computed here, not asserted

Compare the two samples. Same page, same browser, 200 ms apart — the difference is whether you are still inside the gesture. That gap is gate 2.

Gate 5: the failure that happens after the browser

Electron apps do not write the clipboard from the page. They post an IPC message that a main-process handler may or may not act on. The published Notion trace (Notion Desktop 7.6.1) shows the shape as a ternary:

// From the public case study, names restored for reading.
// If the sender check fails, the handler returns undefined.
// No exception. No log. Nothing was copied.
handleRequestFromRenderer.addListener(
  "notion:clipboard:write",
  (event, data) =>
    isNotionWebContents(event.sender)
      ? clipboard.write(data)
      : undefined
);

Read that as a debugging rule: in a bridged app, "the call succeeded" and "the clipboard changed" are two different claims, and only the second one matters. The gate between them is a sender identity check. It fails for a webview that is not the app's own, a secondary window, or a call injected from devtools, and nobody logs it.

The same case study describes a second half: a rich app often writes two payloads — a public one (text plus html, sometimes with a marker comment in the HTML) and a private one keyed to locally saved data. On paste it looks for the marker, matches it against the local store, and when the entry is stale it degrades to text and HTML only. That is the usual rich-text complaint: copy inside the app and paste inside the app looks perfect; paste into another app, or paste after a restart, loses structure.

The first test. Paste into a plain-text target, then into the same app, then into the same app after restarting it. Three targets, three payloads. If they differ, you are looking at a private-format lookup that failed. Rewriting writeText will not fix that.

How to make the agent show its work

Trace the copy path only. Report each hop with its evidence — file,
line or column range — and stop at the system clipboard call. Do not
explain the app's design. Then state two things separately:
(1) what you confirmed exists, (2) what you saw but could not confirm
is reached. Name every silent return or no-op branch you find.

A summary of a bridge will not volunteer that the else-branch of a ternary discards the payload, because nothing in the code looks like an error. Ask for silent branches by name. Related: step 4 of the loop, and the acceptance window when the deciding half is not in the client at all.

Findings and non-findings

ClaimEvidenceConfidenceWhat it does not prove
Gate 1–5 symptoms and the browser divergenceMDN Clipboard API, page last modified 5 Mar 2026HighYour browser build is not the doc; test in the build you ship
A sender check can discard a write with no errorExcerpt in the public Notion case study (Notion Desktop 7.6.1, app.asar, main index.js)HighThat specific build only. Other Electron apps differ
Stale private-format entry degrades to text + HTMLSame case study, web assets cached 13 Jul 2026MediumThat page states the probes describe the probes rather than a captured desktop session — no real paste was observed
Linux/Wayland clipboard managers drop writes—Not verified hereWidely reported, not tested by us. Treat it as a hypothesis to rule out

Next

Sources: MDN, Clipboard API (page modified 2026-03-05) · REA project case study on a copied-text bridge (Notion Desktop 7.6.1; excerpts credited to that page) · Independent site, not affiliated with the REA authors.