{"record":{"id":"75e2cf4664b157ca","repo":"wavetermdev/waveterm","slug":"destination-q-already-exists","errorCode":null,"errorMessage":"destination %q already exists","messagePattern":"destination %q already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshrpc/wshremote/wshremote_file.go","lineNumber":443,"sourceCode":"\t}\n\tif err := os.WriteFile(cleanedPath, []byte{}, 0644); err != nil {\n\t\treturn fmt.Errorf(\"cannot create file %q: %w\", cleanedPath, err)\n\t}\n\treturn nil\n}\n\nfunc (impl *ServerImpl) RemoteFileMoveCommand(ctx context.Context, data wshrpc.CommandFileCopyData) error {\n\tdestUri := data.DestUri\n\tsrcUri := data.SrcUri\n\n\tdestConn, err := connparse.ParseURIAndReplaceCurrentHost(ctx, destUri)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot parse destination URI %q: %w\", srcUri, err)\n\t}\n\tdestPathCleaned := filepath.Clean(wavebase.ExpandHomeDirSafe(destConn.Path))\n\t_, err = os.Stat(destPathCleaned)\n\tif err == nil {\n\t\treturn fmt.Errorf(\"destination %q already exists\", destUri)\n\t} else if !errors.Is(err, fs.ErrNotExist) {\n\t\treturn fmt.Errorf(\"cannot stat destination %q: %w\", destUri, err)\n\t}\n\n\tsrcConn, err := connparse.ParseURIAndReplaceCurrentHost(ctx, srcUri)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot parse source URI %q: %w\", srcUri, err)\n\t}\n\n\tif srcConn.Host != destConn.Host {\n\t\treturn fmt.Errorf(\"cannot move file %q to %q: different hosts\", srcUri, destUri)\n\t}\n\n\tsrcPathCleaned := filepath.Clean(wavebase.ExpandHomeDirSafe(srcConn.Path))\n\terr = os.Rename(srcPathCleaned, destPathCleaned)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot move file %q to %q: %w\", srcPathCleaned, destPathCleaned, err)\n\t}","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshrpc/wshremote/wshremote_file.go#L425-L461","documentation":"Returned when the destination of a move/copy already exists and overwrite was not requested. The destination is quoted via %q.","triggerScenarios":"Calling RemoteFileMoveCommand where the destination file/directory already exists at destConn.Path.","commonSituations":"Re-running a rename script; moving into a directory that already contains a file with the same name; assuming move-overwrite semantics like Unix mv.","solutions":["Check the destination with RemoteFileInfoCommand first and delete it if overwrite is intended.","Pick a unique destination name (timestamp/counter suffix).","If overwrite semantics are required, delete then move, accepting a non-atomic window."],"exampleFix":"// before\nwshclient.RemoteFileMoveCommand(ctx, wshrpc.CommandFileCopyData{SrcUri: src, DestUri: dest}, nil)\n// after\nif _, err := wshclient.RemoteFileInfoCommand(ctx, dest, nil); err == nil {\n    wshclient.RemoteFileDeleteCommand(ctx, dest, nil)\n}\nwshclient.RemoteFileMoveCommand(ctx, wshrpc.CommandFileCopyData{SrcUri: src, DestUri: dest}, nil)","handlingStrategy":"validation","validationCode":"if _, err := wshclient.RemoteFileInfoCommand(ctx, destUri, nil); err == nil {\n    return fmt.Errorf(\"destination %s exists\", destUri)\n}","typeGuard":null,"tryCatchPattern":"err := wshclient.RemoteFileMoveCommand(ctx, data, nil)\nif err != nil && strings.Contains(err.Error(), \"already exists\") {\n    return err // caller decides: delete dest or rename\n}","preventionTips":["Check destination existence before moving","Generate unique destination names","Do not assume mv-style overwrite semantics"],"tags":["filesystem","file-move","conflict","already-exists"],"backgroundTag":"destination-already-exists","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}