wavetermdev/waveterm · error

error parsing source connection: %w

Error message

error parsing source connection: %w

What it means

Move parses both the source and destination URIs via parseConnection; when the source URI fails to parse, the error is wrapped as "error parsing source connection". Move requires well-formed connection URIs to determine hosts (a cross-host Move degrades to copy+delete), so an invalid SrcUri aborts the operation before any file action occurs.

Source

Thrown at pkg/remote/fileshare/wshfs/wshfs.go:224

func Mkdir(ctx context.Context, path string) error {
	log.Printf("Mkdir: %v", path)
	conn, err := parseConnection(ctx, path)
	if err != nil {
		return err
	}
	return wshclient.RemoteMkdirCommand(RpcClient, conn.Path, &wshrpc.RpcOpts{Route: wshutil.MakeConnectionRouteId(conn.Host)})
}

func Move(ctx context.Context, data wshrpc.CommandFileCopyData) error {
	opts := data.Opts
	if opts == nil {
		opts = &wshrpc.FileCopyOpts{}
	}
	log.Printf("Move: srcuri: %v, desturi: %v, opts: %v", data.SrcUri, data.DestUri, opts)
	srcConn, err := parseConnection(ctx, data.SrcUri)
	if err != nil {
		return fmt.Errorf("error parsing source connection: %w", err)
	}
	destConn, err := parseConnection(ctx, data.DestUri)
	if err != nil {
		return fmt.Errorf("error parsing destination connection: %w", err)
	}
	if srcConn.Host != destConn.Host {
		isDir, err := copyInternal(srcConn, destConn, opts)
		if err != nil {
			return fmt.Errorf("cannot copy %q to %q: %w", data.SrcUri, data.DestUri, err)
		}
		return delete_(srcConn, opts.Recursive && isDir)
	}
	return moveInternal(srcConn, destConn, opts)
}

func Copy(ctx context.Context, data wshrpc.CommandFileCopyData) error {
	opts := data.Opts
	if opts == nil {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the wrapped underlying error to see the parse failure reason for SrcUri
  2. Validate/normalize SrcUri is a well-formed connection URI before calling Move
  3. Fix the config/variable supplying SrcUri (empty values are a common cause)
  4. If the source is local, use the proper local path/URI form accepted by connparse

Example fix

// before
wshfs.Move(ctx, wshrpc.CommandFileCopyData{SrcUri: "", DestUri: "wsh://host/tmp/b.txt"})
// after
src := "wsh://host/tmp/a.txt"
if src == "" {
    return errors.New("source uri is empty")
}
wshfs.Move(ctx, wshrpc.CommandFileCopyData{SrcUri: src, DestUri: "wsh://host/tmp/b.txt"})
Defensive patterns

Strategy: validation

Validate before calling

if data.SrcUri == "" {
    return errors.New("source uri is required for wshfs.Move")
}
if !strings.Contains(data.SrcUri, "://") && !filepath.IsAbs(data.SrcUri) {
    return fmt.Errorf("source uri %q is not a valid connection uri", data.SrcUri)
}

Type guard

func validSrcUri(d wshrpc.CommandFileCopyData) bool {
    u, err := url.Parse(d.SrcUri)
    return d.SrcUri != "" && err == nil && (u.Scheme != "" || filepath.IsAbs(d.SrcUri))
}

Try / catch

err := wshfs.Move(ctx, data)
if err != nil {
    if strings.Contains(err.Error(), "error parsing source connection") {
        return fmt.Errorf("bad source uri %q: %w", data.SrcUri, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling wshfs.Move (via FileMoveCommand) with CommandFileCopyData.SrcUri that connparse cannot parse — empty string, malformed scheme, invalid characters — while DestUri may be valid.

Common situations: Source path built from user input or config with a missing/typo'd "wsh://" scheme; empty SrcUri from an unset variable; dragging/pasting a plain Windows-style or relative path where a connection URI is expected.

Related errors


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