wavetermdev/waveterm · error

stream broker route id not available for file copy

Error message

stream broker route id not available for file copy

What it means

Before streaming the file, the command checks that wshfs.RpcClientRouteId is set — the route id of the local RPC client registered with the stream broker. If it is empty, no stream route has been established for this client and the streaming copy cannot proceed. This indicates the wsh RPC client was not fully initialized (broker registration not done) at the time of the call.

Source

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

		return false, fmt.Errorf("copying directories is not supported")
	}
	if srcFileInfo.Size > RemoteFileTransferSizeLimit {
		return false, fmt.Errorf("file %q size %d exceeds transfer limit of %d bytes", data.SrcUri, srcFileInfo.Size, RemoteFileTransferSizeLimit)
	}

	destFilePath, err := prepareDestForCopy(destPathCleaned, fspath.Base(srcConn.Path), destHasSlash, opts.Overwrite)
	if err != nil {
		return false, err
	}

	destFile, err := os.OpenFile(destFilePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, srcFileInfo.Mode)
	if err != nil {
		return false, fmt.Errorf("cannot create destination file %q: %w", destFilePath, err)
	}
	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)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Ensure the wsh RPC client is fully initialized (RpcClient registered with StreamBroker, RpcClientRouteId set) before invoking file copy commands.
  2. Wait for connection/client bootstrap to complete in your app before issuing copy commands.
  3. If embedding the package, register the client route the same way wsh main initialization does (StreamBroker.CreateStreamReader/Writer flow requires a non-empty local route id).
  4. Upgrade Wave Terminal if a version change caused the client route to no longer be set automatically.

Example fix

// before
ok, err := srv.RemoteFileCopyCommand(ctx, copyData) // run immediately after start
// after
if wshfs.RpcClientRouteId == "" {
    time.Sleep(500 * time.Millisecond) // or wait on client-ready signal
}
ok, err := srv.RemoteFileCopyCommand(ctx, copyData)
Defensive patterns

Strategy: try-catch

Validate before calling

if wshfs.RpcClient == nil || wshfs.RpcClientRouteId == "" {
    return errors.New("wsh rpc client not initialized; wait for client bootstrap before copying")
}

Type guard

func streamBrokerReady(rpc *wshutil.WshRpc) bool { return rpc != nil && wshfs.RpcClientRouteId != "" }

Try / catch

ok, err := RemoteFileCopyCommand(ctx, data)
if err != nil {
    if strings.Contains(err.Error(), "stream broker route id not available") {
        // retry after client bootstrap completes, or surface an init-order bug
    }
    return err
}

Prevention

When it happens

Trigger: RemoteFileCopyCommand reaches the stream setup on the local side while wshfs.RpcClientRouteId == "", i.e. the RpcClient exists but its route id was never assigned/registered with StreamBroker, typically because the wsh client/broker bootstrap hasn't completed in this process.

Common situations: Calling the copy command very early in client startup before the RPC client route registration completes; using the wshremote server machinery outside a fully initialized Wave/wsh environment; a regression where RpcClient is created without StreamBroker registration.

Related errors


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