Symptom
scripts/test-clipboard-formats.ps1 intermittently fails with the virtual_only
fixture missing. The summary shows six of seven fixtures observed, timed_out: true,
read_failures: 0, and an empty fixture_failures list:
{"event":"summary","expected_fixtures":7,"observed_fixtures":6,"passed_fixtures":6,
"fixture_failures":[],"read_failures":0,"timed_out":true,"passed":false}
The writer process prints the underlying cause on stderr:
clipboard fixture writer failed: failed to write fixture virtual_only:
Empty clipboard error, code = OSError(1418): Thread does not have a clipboard open.
Error 1418 is ERROR_CLIPBOARD_NOT_OPEN, so this is not ordinary
ERROR_ACCESS_DENIED contention -- set_fixture already retries that ten times.
clipboard_rs successfully opened the clipboard and then found its own handle
gone by the time it called EmptyClipboard.
Suspected cause
virtual_only is written immediately after the two delayed fixtures. The delayed
writer owns a hidden window on the same thread that clipboard_rs writes from.
When the next fixture empties the clipboard, that window receives
WM_RENDERALLFORMATS, whose handler calls OpenClipboard/CloseClipboard on
that same thread. A nested open and close around an in-flight clipboard_rs
write would leave the writer's clipboard closed underneath it, which matches
error 1418 exactly.
The fix is likely to serialize the delayed owner's render against fixture writes,
or to move the delayed writer window onto its own thread, rather than to add more
retries.
Not a regression from #163
Measured by building the probe from main and from the #163 branch and running
each fifteen times on the same machine:
| build |
failures |
fixture |
baseline (aa06864) |
1 / 15 |
virtual_only |
| #163 branch |
1 / 15 |
virtual_only |
Both fail the same way, so #163 neither introduces nor fixes this. It is called
out here because #163's clipboard-contention retries are adjacent to it and the
distinction is easy to lose later.
Impact
CI does not run this suite -- it is a local Windows-only script -- so this costs
a re-run rather than a red build. It does undermine the suite's value as evidence:
a single red run currently cannot be read as a capture regression without checking
which fixture went missing and whether read_failures was zero.
docs/CLIPBOARD_RELIABILITY.md documents the flake and points here.
Symptom
scripts/test-clipboard-formats.ps1intermittently fails with thevirtual_onlyfixture missing. The summary shows six of seven fixtures observed,
timed_out: true,read_failures: 0, and an emptyfixture_failureslist:The writer process prints the underlying cause on stderr:
Error 1418 is
ERROR_CLIPBOARD_NOT_OPEN, so this is not ordinaryERROR_ACCESS_DENIEDcontention --set_fixturealready retries that ten times.clipboard_rssuccessfully opened the clipboard and then found its own handlegone by the time it called
EmptyClipboard.Suspected cause
virtual_onlyis written immediately after the two delayed fixtures. The delayedwriter owns a hidden window on the same thread that
clipboard_rswrites from.When the next fixture empties the clipboard, that window receives
WM_RENDERALLFORMATS, whose handler callsOpenClipboard/CloseClipboardonthat same thread. A nested open and close around an in-flight
clipboard_rswrite would leave the writer's clipboard closed underneath it, which matches
error 1418 exactly.
The fix is likely to serialize the delayed owner's render against fixture writes,
or to move the delayed writer window onto its own thread, rather than to add more
retries.
Not a regression from #163
Measured by building the probe from
mainand from the #163 branch and runningeach fifteen times on the same machine:
aa06864)virtual_onlyvirtual_onlyBoth fail the same way, so #163 neither introduces nor fixes this. It is called
out here because #163's clipboard-contention retries are adjacent to it and the
distinction is easy to lose later.
Impact
CI does not run this suite -- it is a local Windows-only script -- so this costs
a re-run rather than a red build. It does undermine the suite's value as evidence:
a single red run currently cannot be read as a capture regression without checking
which fixture went missing and whether
read_failureswas zero.docs/CLIPBOARD_RELIABILITY.mddocuments the flake and points here.