{"record":{"id":"d5e0492883470627","repo":"wavetermdev/waveterm","slug":"copy-failed","errorCode":null,"errorMessage":"Copy failed:","messagePattern":"Copy failed:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/app/view/preview/preview-directory.tsx","lineNumber":719,"sourceCode":"    }, [filteredData]);\n\n    const entryManagerPropsAtom = useState(\n        atom<EntryManagerOverlayProps>(null) as PrimitiveAtom<EntryManagerOverlayProps>\n    )[0];\n    const [entryManagerProps, setEntryManagerProps] = useAtom(entryManagerPropsAtom);\n\n    const { refs, floatingStyles, context } = useFloating({\n        open: !!entryManagerProps,\n        onOpenChange: () => setEntryManagerProps(undefined),\n        middleware: [offset(({ rects }) => -rects.reference.height / 2 - rects.floating.height / 2)],\n    });\n\n    const handleDropCopy = useCallback(\n        async (data: CommandFileCopyData, isDir: boolean) => {\n            try {\n                await env.rpc.FileCopyCommand(TabRpcClient, data, { timeout: data.opts.timeout });\n            } catch (e) {\n                console.warn(\"Copy failed:\", e);\n                const copyError = `${e}`;\n                const allowRetry = copyError.includes(overwriteError) || copyError.includes(mergeError);\n                let errorMsg: ErrorMsg;\n                if (allowRetry) {\n                    errorMsg = {\n                        status: \"Confirm Overwrite File(s)\",\n                        text: \"This copy operation will overwrite an existing file. Would you like to continue?\",\n                        level: \"warning\",\n                        buttons: [\n                            {\n                                text: \"Delete Then Copy\",\n                                onClick: async () => {\n                                    data.opts.overwrite = true;\n                                    await handleDropCopy(data, isDir);\n                                },\n                            },\n                            {\n                                text: \"Sync\",","sourceCodeStart":701,"sourceCodeEnd":737,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/frontend/app/view/preview/preview-directory.tsx#L701-L737","documentation":"DirectoryPreview's handleDropCopy invokes the FileCopyCommand RPC for a drop/copy operation; on rejection it logs 'Copy failed:' with the error. If the error indicates an overwrite/merge conflict (overwriteError/mergeError), the UI offers a retry with overwrite/merge options instead of failing outright.","triggerScenarios":"FileCopyCommand rejects (timeout or backend error): destination file exists without overwrite permission, source missing, permission denied, or the configured copy timeout elapses for large copies.","commonSituations":"Copying onto existing files without overwrite consent; copying large trees that exceed data.opts.timeout; copying to a read-only or full destination; dragging from a source that changed between drag start and drop.","solutions":["If the UI shows 'Confirm Overwrite File(s)', accept to retry with overwrite/merge flags","Increase the copy timeout (data.opts.timeout) for large copies and retry","Verify source files exist and the destination has write permission","Refresh the preview and retry the copy"],"exampleFix":"// before\nawait env.rpc.FileCopyCommand(TabRpcClient, data, { timeout: data.opts.timeout });\n// after\ntry {\n    await env.rpc.FileCopyCommand(TabRpcClient, data, { timeout: data.opts.timeout });\n} catch (e) {\n    if (`${e}`.includes(overwriteError)) {\n        await env.rpc.FileCopyCommand(TabRpcClient, { ...data, opts: { ...data.opts, overwrite: true } }, { timeout: data.opts.timeout });\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"// before copying, detect conflicts client-side when possible\nconst conflict = await destExists(data) && !data.opts.overwrite && !data.opts.merge;\nif (conflict) {\n    setErrorMsg({ status: 'Confirm Overwrite File(s)', text: 'Destination exists. Overwrite?', level: 'warning' });\n    return;\n}","typeGuard":"function isRetryableCopyConflict(copyError: string, overwriteError: string, mergeError: string): boolean {\n    return copyError.includes(overwriteError) || copyError.includes(mergeError);\n}","tryCatchPattern":"try {\n    await env.rpc.FileCopyCommand(TabRpcClient, data, { timeout: data.opts.timeout });\n} catch (e) {\n    console.warn('Copy failed:', e);\n    const copyError = `${e}`;\n    if (copyError.includes(overwriteError) || copyError.includes(mergeError)) {\n        setErrorMsg({ status: 'Confirm Overwrite File(s)', text: copyError, level: 'warning' }); // offer retry with overwrite/merge\n    } else {\n        setErrorMsg({ status: 'Copy Failed', text: copyError });\n    }\n}","preventionTips":["Check for existing destination files before initiating a drop copy","Set a generous timeout (data.opts.timeout) for large copy operations","Treat overwriteError/mergeError as retryable, everything else as terminal","Verify destination free space and write permissions before large copies"],"tags":["rpc","filesystem","copy","drag-and-drop","preview"],"backgroundTag":"file-copy-rpc-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}