wavetermdev/waveterm · error

destination %q already exists

Error message

destination %q already exists

What it means

Returned when the destination of a move/copy already exists and overwrite was not requested. The destination is quoted via %q.

Source

Thrown at pkg/wshrpc/wshremote/wshremote_file.go:443

	}
	if err := os.WriteFile(cleanedPath, []byte{}, 0644); err != nil {
		return fmt.Errorf("cannot create file %q: %w", cleanedPath, err)
	}
	return nil
}

func (impl *ServerImpl) RemoteFileMoveCommand(ctx context.Context, data wshrpc.CommandFileCopyData) error {
	destUri := data.DestUri
	srcUri := data.SrcUri

	destConn, err := connparse.ParseURIAndReplaceCurrentHost(ctx, destUri)
	if err != nil {
		return fmt.Errorf("cannot parse destination URI %q: %w", srcUri, err)
	}
	destPathCleaned := filepath.Clean(wavebase.ExpandHomeDirSafe(destConn.Path))
	_, err = os.Stat(destPathCleaned)
	if err == nil {
		return fmt.Errorf("destination %q already exists", destUri)
	} else if !errors.Is(err, fs.ErrNotExist) {
		return fmt.Errorf("cannot stat destination %q: %w", destUri, err)
	}

	srcConn, err := connparse.ParseURIAndReplaceCurrentHost(ctx, srcUri)
	if err != nil {
		return fmt.Errorf("cannot parse source URI %q: %w", srcUri, err)
	}

	if srcConn.Host != destConn.Host {
		return fmt.Errorf("cannot move file %q to %q: different hosts", srcUri, destUri)
	}

	srcPathCleaned := filepath.Clean(wavebase.ExpandHomeDirSafe(srcConn.Path))
	err = os.Rename(srcPathCleaned, destPathCleaned)
	if err != nil {
		return fmt.Errorf("cannot move file %q to %q: %w", srcPathCleaned, destPathCleaned, err)
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check the destination with RemoteFileInfoCommand first and delete it if overwrite is intended.
  2. Pick a unique destination name (timestamp/counter suffix).
  3. If overwrite semantics are required, delete then move, accepting a non-atomic window.

Example fix

// before
wshclient.RemoteFileMoveCommand(ctx, wshrpc.CommandFileCopyData{SrcUri: src, DestUri: dest}, nil)
// after
if _, err := wshclient.RemoteFileInfoCommand(ctx, dest, nil); err == nil {
    wshclient.RemoteFileDeleteCommand(ctx, dest, nil)
}
wshclient.RemoteFileMoveCommand(ctx, wshrpc.CommandFileCopyData{SrcUri: src, DestUri: dest}, nil)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := wshclient.RemoteFileInfoCommand(ctx, destUri, nil); err == nil {
    return fmt.Errorf("destination %s exists", destUri)
}

Try / catch

err := wshclient.RemoteFileMoveCommand(ctx, data, nil)
if err != nil && strings.Contains(err.Error(), "already exists") {
    return err // caller decides: delete dest or rename
}

Prevention

When it happens

Trigger: Calling RemoteFileMoveCommand where the destination file/directory already exists at destConn.Path.

Common situations: 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.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/75e2cf4664b157ca. Report an issue: GitHub.