wavetermdev/waveterm · error
Copy failed:
Error message
Copy failed:
What it means
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.
Source
Thrown at frontend/app/view/preview/preview-directory.tsx:719
}, [filteredData]);
const entryManagerPropsAtom = useState(
atom<EntryManagerOverlayProps>(null) as PrimitiveAtom<EntryManagerOverlayProps>
)[0];
const [entryManagerProps, setEntryManagerProps] = useAtom(entryManagerPropsAtom);
const { refs, floatingStyles, context } = useFloating({
open: !!entryManagerProps,
onOpenChange: () => setEntryManagerProps(undefined),
middleware: [offset(({ rects }) => -rects.reference.height / 2 - rects.floating.height / 2)],
});
const handleDropCopy = useCallback(
async (data: CommandFileCopyData, isDir: boolean) => {
try {
await env.rpc.FileCopyCommand(TabRpcClient, data, { timeout: data.opts.timeout });
} catch (e) {
console.warn("Copy failed:", e);
const copyError = `${e}`;
const allowRetry = copyError.includes(overwriteError) || copyError.includes(mergeError);
let errorMsg: ErrorMsg;
if (allowRetry) {
errorMsg = {
status: "Confirm Overwrite File(s)",
text: "This copy operation will overwrite an existing file. Would you like to continue?",
level: "warning",
buttons: [
{
text: "Delete Then Copy",
onClick: async () => {
data.opts.overwrite = true;
await handleDropCopy(data, isDir);
},
},
{
text: "Sync",View on GitHub (pinned to a4447c1563)
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
Example fix
// before
await env.rpc.FileCopyCommand(TabRpcClient, data, { timeout: data.opts.timeout });
// after
try {
await env.rpc.FileCopyCommand(TabRpcClient, data, { timeout: data.opts.timeout });
} catch (e) {
if (`${e}`.includes(overwriteError)) {
await env.rpc.FileCopyCommand(TabRpcClient, { ...data, opts: { ...data.opts, overwrite: true } }, { timeout: data.opts.timeout });
} else {
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// before copying, detect conflicts client-side when possible
const conflict = await destExists(data) && !data.opts.overwrite && !data.opts.merge;
if (conflict) {
setErrorMsg({ status: 'Confirm Overwrite File(s)', text: 'Destination exists. Overwrite?', level: 'warning' });
return;
} Type guard
function isRetryableCopyConflict(copyError: string, overwriteError: string, mergeError: string): boolean {
return copyError.includes(overwriteError) || copyError.includes(mergeError);
} Try / catch
try {
await env.rpc.FileCopyCommand(TabRpcClient, data, { timeout: data.opts.timeout });
} catch (e) {
console.warn('Copy failed:', e);
const copyError = `${e}`;
if (copyError.includes(overwriteError) || copyError.includes(mergeError)) {
setErrorMsg({ status: 'Confirm Overwrite File(s)', text: copyError, level: 'warning' }); // offer retry with overwrite/merge
} else {
setErrorMsg({ status: 'Copy Failed', text: copyError });
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Rename failed: ${errorText}
- Delete failed: ${errorText}
- creating file: %w
- getting file info: %w
- initializing file with empty write: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/d5e0492883470627.
Report an issue: GitHub.