wavetermdev/waveterm · error

stream broker not available

Error message

stream broker not available

What it means

Read streams file contents through RpcClient.StreamBroker; if the global RpcClient was initialized but its StreamBroker is nil, the streaming machinery does not exist and Read aborts with this error. The broker is normally set up during RPC client initialization, so a nil broker indicates incomplete initialization.

Source

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

	conn, err := connparse.ParseURIAndReplaceCurrentHost(ctx, path)
	if err != nil {
		return nil, fmt.Errorf("error parsing connection %s: %w", path, err)
	}
	return conn, nil
}

func Read(ctx context.Context, data wshrpc.FileData) (*wshrpc.FileData, error) {
	if data.Info == nil {
		return nil, fmt.Errorf("file info is required")
	}
	log.Printf("Read: %v", data.Info.Path)
	conn, err := parseConnection(ctx, data.Info.Path)
	if err != nil {
		return nil, err
	}
	broker := RpcClient.StreamBroker
	if broker == nil {
		return nil, fmt.Errorf("stream broker not available")
	}
	if RpcClientRouteId == "" {
		return nil, fmt.Errorf("no route id available")
	}
	readerRouteId := RpcClientRouteId
	writerRouteId := wshutil.MakeConnectionRouteId(conn.Host)
	reader, streamMeta := broker.CreateStreamReader(readerRouteId, writerRouteId, 256*1024)
	defer reader.Close()
	go func() {
		<-ctx.Done()
		reader.Close()
	}()
	byteRange := ""
	if data.At != nil && data.At.Size > 0 {
		byteRange = fmt.Sprintf("%d-%d", data.At.Offset, data.At.Offset+int64(data.At.Size)-1)
	}
	remoteData := wshrpc.CommandRemoteFileStreamData{
		Path:       conn.Path,

View on GitHub (pinned to a4447c1563)

Solutions

  1. Ensure RpcClient is initialized with a StreamBroker (wshutil.NewWshRpc / broker setup) before calling Read
  2. Verify the code path that installs StreamBroker actually runs in your binary (main-server or wshcmd-connserver)
  3. Check initialization order — Read must not be called before RPC setup finishes

Example fix

// before
wshfs.RpcClient = wshutil.NewWshRpc() // StreamBroker never set
// after
rpc := wshutil.NewWshRpc()
rpc.StreamBroker = wshutil.NewWshStreamBroker() // install broker before use
wshfs.RpcClient = rpc
Defensive patterns

Strategy: fallback

Validate before calling

if wshfs.RpcClient == nil || wshfs.RpcClient.StreamBroker == nil {
    return errors.New("wshfs RPC client or stream broker not initialized")
}

Type guard

func brokerReady() bool {
    return wshfs.RpcClient != nil && wshfs.RpcClient.StreamBroker != nil
}

Try / catch

out, err := wshfs.Read(ctx, data)
if err != nil {
    if strings.Contains(err.Error(), "stream broker not available") {
        return fmt.Errorf("streaming unsupported in this build/init: %w", err) // fallback: use non-streaming RPC
    }
    return err
}

Prevention

When it happens

Trigger: Calling wshfs.Read before (or without) proper WshRpc initialization where StreamBroker was never assigned; using a plain WshRpc instance that only supports request/response RPCs.

Common situations: Embedding wshfs in a custom binary that constructs WshRpc manually without installing a stream broker; initialization order bug where Read runs before setup completes; a version change altered broker setup.

Related errors


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