{"record":{"id":"441794f7afa389c1","repo":"siyuan-note/siyuan","slug":"open-clipboard-timeout","errorCode":null,"errorMessage":"open clipboard timeout","messagePattern":"open clipboard timeout","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/clipboard_windows.go","lineNumber":161,"sourceCode":"\t\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], c)\n\t\t\toffset += 2\n\t\t}\n\t}\n\treturn buf, nil\n}\n\n// waitOpenClipboard 在限定时间内重试打开剪贴板。\n// 同一时刻仅一进程可持有剪贴板（OpenClipboard 成功）。\n// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-openclipboard\nfunc waitOpenClipboard() error {\n\tdeadline := time.Now().Add(time.Second)\n\tfor time.Now().Before(deadline) {\n\t\tif w32.OpenClipboard(0) {\n\t\t\treturn nil\n\t\t}\n\t\ttime.Sleep(time.Millisecond)\n\t}\n\treturn errors.New(\"open clipboard timeout\")\n}\n","sourceCodeStart":143,"sourceCodeEnd":163,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/clipboard_windows.go#L143-L163","documentation":"Returned by waitOpenClipboard after retrying w32.OpenClipboard once per millisecond for up to one second. Windows enforces a single clipboard owner: only one process can hold the clipboard open at a time, so OpenClipboard fails while another app (clipboard viewer, remote-desktop tool, antivirus) has it open.","triggerScenarios":"Calling WriteFilePaths on Windows while another process holds the clipboard open for longer than 1 second. The 1-second deadline in waitOpenClipboard is exceeded before OpenClipboard succeeds.","commonSituations":"A clipboard-monitoring utility (e.g. a clipboard manager, snipping tool, or RDP/Teams clip-share) holding the clipboard; antivirus inspecting clipboard contents; rapid repeated copy operations; running under a remote-desktop session that synchronizes the clipboard.","solutions":["Close other clipboard-monitoring tools (clipboard managers, RDP clipboard sync, screen-snipping tools) and retry.","Retry the copy operation — the lock is usually brief and a second attempt shortly after often succeeds.","If the contention is persistent, raise the retry window or retry at the caller level rather than lengthening the tight loop."],"exampleFix":"// before\nif err := util.WriteFilePaths([]string{absPath}); err != nil {\n    return err\n}\n\n// after\nvar err error\nfor attempt := 0; attempt < 3; attempt++ {\n    if err = util.WriteFilePaths([]string{absPath}); err == nil {\n        break\n    }\n    time.Sleep(200 * time.Millisecond)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"var err error\nfor attempt := 0; attempt < 3; attempt++ {\n    if err = util.WriteFilePaths(paths); err == nil || !strings.Contains(err.Error(), \"open clipboard timeout\") {\n        break\n    }\n    time.Sleep(300 * time.Millisecond)\n}","preventionTips":["Close clipboard-monitoring utilities and RDP clipboard sync before large copy operations.","Surface 'clipboard busy, retrying' to the user instead of failing on the first timeout."],"tags":["clipboard","windows","win32","concurrency"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}