Skip to content

Clipboard format fixtures: virtual_only intermittently fails to publish with ERROR_CLIPBOARD_NOT_OPEN #164

Description

@btsouth

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: desktopWindows desktop applicationrustPull requests that update rust codetestingAutomated tests and test infrastructure

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions