wavetermdev/waveterm · error
error starting file stream for %q: %w
Error message
error starting file stream for %q: %w
What it means
RemoteFileCopyCommand in wshremote wraps the failure of the initial RemoteFileStreamCommand RPC call that opens the read stream on the source connection. This wrapper error is raised when the writer-side stream could not be started, so the copy aborts before any bytes are transferred. The underlying cause is always in the wrapped error (auth, route, or stream-open failure).
Source
Thrown at pkg/wshrpc/wshremote/wshremote_file.go:187
defer destFile.Close()
if wshfs.RpcClientRouteId == "" {
return false, fmt.Errorf("stream broker route id not available for file copy")
}
writerRouteId := wshutil.MakeConnectionRouteId(srcConn.Host)
reader, streamMeta := wshfs.RpcClient.StreamBroker.CreateStreamReader(wshfs.RpcClientRouteId, writerRouteId, 256*1024)
log.Printf("RemoteFileCopyCommand: readroute=%s writeroute=%s", streamMeta.ReaderRouteId, streamMeta.WriterRouteId)
defer reader.Close()
go func() {
<-readCtx.Done()
reader.Close()
}()
streamData := wshrpc.CommandRemoteFileStreamData{
Path: srcConn.Path,
StreamMeta: *streamMeta,
}
if _, err = wshclient.RemoteFileStreamCommand(wshfs.RpcClient, streamData, &wshrpc.RpcOpts{Route: writerRouteId}); err != nil {
return false, fmt.Errorf("error starting file stream for %q: %w", data.SrcUri, err)
}
if _, err = io.Copy(destFile, reader); err != nil {
return false, fmt.Errorf("error copying file %q to %q: %w", data.SrcUri, data.DestUri, err)
}
totalTime := time.Since(copyStart).Seconds()
totalMegaBytes := float64(srcFileInfo.Size) / 1024 / 1024
rate := float64(0)
if totalTime > 0 {
rate = totalMegaBytes / totalTime
}
log.Printf("RemoteFileCopyCommand: done; 1 file copied in %.3fs, total of %.4f MB, %.2f MB/s\n", totalTime, totalMegaBytes, rate)
return false, nil
}
func (impl *ServerImpl) RemoteListEntriesCommand(ctx context.Context, data wshrpc.CommandRemoteListEntriesData) chan wshrpc.RespOrErrorUnion[wshrpc.CommandRemoteListEntriesRtnData] {
ch := make(chan wshrpc.RespOrErrorUnion[wshrpc.CommandRemoteListEntriesRtnData], 16)
go func() {View on GitHub (pinned to a4447c1563)
Solutions
- Inspect the wrapped cause (%w) to identify whether it is file-not-found, permission, or RPC routing.
- Verify the source URI exists via RemoteFileInfoCommand before copying.
- Check that the remote connection is alive and the writerRouteId is valid/registered.
- Retry the copy after re-establishing the connection.
Example fix
// before
_, err := wshclient.RemoteFileCopyCommand(ctx, copyData, nil)
// after
info, err := wshclient.RemoteFileInfoCommand(ctx, srcUri, nil)
if err != nil {
return fmt.Errorf("source missing, aborting copy: %w", err)
}
_, err = wshclient.RemoteFileCopyCommand(ctx, copyData, nil) Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := wshclient.RemoteFileInfoCommand(ctx, srcUri, nil); err != nil {
return fmt.Errorf("source unavailable: %w", err)
} Try / catch
err := wshclient.RemoteFileCopyCommand(ctx, data, nil)
var startErr error
if err != nil && strings.Contains(err.Error(), "error starting file stream") {
startErr = err // wrapped cause: check connection/route, then retry
} Prevention
- Verify source file exists before copying
- Keep connections alive and re-dial before long copies
- Log the wrapped cause, not just the wrapper
When it happens
Trigger: Calling RemoteFileCopyCommand where wshclient.RemoteFileStreamCommand (routed to writerRouteId) returns an error, e.g. the source file does not exist, RPC routing fails, or the remote peer rejects the stream request.
Common situations: Copying a file whose source path was deleted between listing and copy; stale or invalid writer route id; remote connection dropped mid-copy setup; permission denied on the source file.
Related errors
- starting file stream: %w
- unable to obtain remote info from connserver: %w
- cannot get info for source file %q: %w
- stream broker route id not available for file copy
- error copying file %q to %q: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/5bcb73f8636bb1c2.
Report an issue: GitHub.