{"record":{"id":"97036524b31b81d5","repo":"wavetermdev/waveterm","slug":"move-internal-src-and-dest-hosts-do-not-match","errorCode":null,"errorMessage":"move internal, src and dest hosts do not match","messagePattern":"move internal, src and dest hosts do not match","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/fileshare/wshfs/wshfs.go","lineNumber":282,"sourceCode":"\treturn delete_(conn, data.Recursive)\n}\n\nfunc delete_(conn *connparse.Connection, recursive bool) error {\n\treturn wshclient.RemoteFileDeleteCommand(RpcClient, wshrpc.CommandDeleteFileData{Path: conn.Path, Recursive: recursive}, &wshrpc.RpcOpts{Route: wshutil.MakeConnectionRouteId(conn.Host)})\n}\n\nfunc Join(ctx context.Context, path string, parts ...string) (*wshrpc.FileInfo, error) {\n\tlog.Printf(\"Join: %v\", path)\n\tconn, err := parseConnection(ctx, path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn wshclient.RemoteFileJoinCommand(RpcClient, append([]string{conn.Path}, parts...), &wshrpc.RpcOpts{Route: wshutil.MakeConnectionRouteId(conn.Host)})\n}\n\nfunc moveInternal(srcConn, destConn *connparse.Connection, opts *wshrpc.FileCopyOpts) error {\n\tif srcConn.Host != destConn.Host {\n\t\treturn fmt.Errorf(\"move internal, src and dest hosts do not match\")\n\t}\n\tif opts == nil {\n\t\topts = &wshrpc.FileCopyOpts{}\n\t}\n\ttimeout := opts.Timeout\n\tif timeout == 0 {\n\t\ttimeout = DefaultTimeout.Milliseconds()\n\t}\n\treturn wshclient.RemoteFileMoveCommand(RpcClient, wshrpc.CommandFileCopyData{SrcUri: srcConn.GetFullURI(), DestUri: destConn.GetFullURI(), Opts: opts}, &wshrpc.RpcOpts{Route: wshutil.MakeConnectionRouteId(destConn.Host), Timeout: timeout})\n}\n\nfunc copyInternal(srcConn, destConn *connparse.Connection, opts *wshrpc.FileCopyOpts) (bool, error) {\n\tif opts == nil {\n\t\topts = &wshrpc.FileCopyOpts{}\n\t}\n\ttimeout := opts.Timeout\n\tif timeout == 0 {\n\t\ttimeout = DefaultTimeout.Milliseconds()","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/remote/fileshare/wshfs/wshfs.go#L264-L300","documentation":"moveInternal is wshfs's same-host fast path: it issues a single RemoteFileMoveCommand RPC to the destination host. If the source and destination hosts differ, it refuses with this sentinel message instead of doing a silent cross-host copy — cross-host moves must go through the copy+delete path in Move. This is a defensive invariant check; Move already routes cross-host cases to copyInternal, so reaching this error indicates a logic inconsistency or direct misuse.","triggerScenarios":"moveInternal being invoked with srcConn.Host != destConn.Host — either called directly by internal code with mismatched parsed connections, or a race where host comparison in Move passed but connections differ. In normal use via Move it should be unreachable.","commonSituations":"Custom code calling moveInternal (or an older variant) directly without the host check; refactors that bypass Move's host-comparison branch.","solutions":["Route cross-host operations through wshfs.Move, which handles them via copyInternal + delete.","If you control the URIs, ensure source and destination share the same connection host so the same-host rename path applies.","If you see this from stock Move usage, report it as a bug — the guard should be unreachable."],"exampleFix":"// before\n// calling moveInternal directly with different hosts\nmoveInternal(srcConn, destConn, opts)\n// after\nMove(ctx, wshrpc.CommandFileCopyData{SrcUri: srcConn.GetFullURI(), DestUri: destConn.GetFullURI(), Opts: opts})","handlingStrategy":"validation","validationCode":"src, _ := connparse.ParseConnection(ctx, srcUri)\ndst, _ := connparse.ParseConnection(ctx, destUri)\nif src.Host != dst.Host {\n    // use Move (copy+delete fallback), not the same-host move path\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use the same-host rename path when parsed hosts match.","Route all user-driven moves through wshfs.Move.","Treat this error as an internal invariant violation and file a bug if hit via public API."],"tags":["file-transfer","invariant","go"],"backgroundTag":"cross-host-move-unsupported","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}