SubtitleEdit/subtitleedit · error · InvalidOperationException
Failed to open clipboard
Error message
Failed to open clipboard
What it means
Thrown in CopyImageToClipboardWindows when OpenClipboard(IntPtr.Zero) returns false — the Windows clipboard could not be opened, typically because another application currently has it open. OpenClipboard is exclusive: only one window may have it open at a time. The allocated hGlobal is freed before throwing. This is one of the most common clipboard failures on Windows.
Source
Thrown at src/ui/Logic/ClipboardHelper.cs:261
// Write pixel data (flip vertically for bottom-up DIB)
IntPtr pixelPtr = IntPtr.Add(ptr, headerSize);
for (int y = 0; y < height; y++)
{
int sourceOffset = (height - 1 - y) * stride;
IntPtr destPtr = IntPtr.Add(pixelPtr, y * stride);
Marshal.Copy(pixels, sourceOffset, destPtr, stride);
}
}
finally
{
GlobalUnlock(hGlobal);
}
// Open clipboard and set data
if (!OpenClipboard(IntPtr.Zero))
{
GlobalFree(hGlobal);
throw new InvalidOperationException("Failed to open clipboard");
}
try
{
if (!EmptyClipboard())
{
GlobalFree(hGlobal);
throw new InvalidOperationException("Failed to empty clipboard");
}
if (SetClipboardData(CF_DIB, hGlobal) == IntPtr.Zero)
{
GlobalFree(hGlobal);
throw new InvalidOperationException("Failed to set clipboard data");
}
// Clipboard now owns the memory
hGlobal = IntPtr.Zero;View on GitHub (pinned to 17a9f07487)
Solutions
- Retry OpenClipboard with small delays (e.g. up to N attempts, 50-100ms apart) before giving up, mirroring the SetTextAsync retry pattern.
- Close other clipboard-viewer/manager applications and retry.
- If running under RDP/VM, reconnect or disable clipboard redirection temporarily.
- Check Marshal.GetLastWin32Error() (ERROR_ACCESS_DENIED = 5 confirms contention).
Example fix
// before
if (!OpenClipboard(IntPtr.Zero)) { GlobalFree(hGlobal); throw new InvalidOperationException("Failed to open clipboard"); }
// after - bounded retry, same strategy as SetTextAsync
bool opened = false;
for (int i = 0; i < 10 && !opened; i++) { opened = OpenClipboard(IntPtr.Zero); if (!opened) Thread.Sleep(50); }
if (!opened) { GlobalFree(hGlobal); throw new InvalidOperationException($"Failed to open clipboard (Win32 error {Marshal.GetLastWin32Error()})."); } Defensive patterns
Strategy: retry
Try / catch
// Mirror the SetTextAsync retry: OpenClipboard is exclusive and commonly contended.
bool opened = false;
for (int i = 0; i < 10 && !opened; i++) { opened = OpenClipboard(IntPtr.Zero); if (!opened) Thread.Sleep(50); }
if (!opened) { GlobalFree(hGlobal); throw new InvalidOperationException($"Failed to open clipboard (Win32 {Marshal.GetLastWin32Error()})."); } Prevention
- Retry OpenClipboard with short delays (it is exclusive).
- Close clipboard viewers/managers/VM redirectors that hold it open.
- Prefer passing a real window handle as the owner.
When it happens
Trigger: Another process/window holds the clipboard open (clipboard viewers, remote-desktop/VM tools, screen-grabbers, office clipboard managers); retrying too quickly after a previous open; a process that opened the clipboard and stalled without closing it.
Common situations: Remote Desktop or a VM integration service holding the clipboard; a clipboard manager (ClipX, Ditto, Office); antivirus inspecting clipboard content; rapid successive copy operations.
Related errors
- Failed to allocate global memory
- Failed to lock global memory
- Failed to empty clipboard
- Failed to set clipboard data
- Failed to decode bitmap
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/ade1bfc1f28d42df.
Report an issue: GitHub.