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
- Ensure RpcClient is initialized with a StreamBroker (wshutil.NewWshRpc / broker setup) before calling Read
- Verify the code path that installs StreamBroker actually runs in your binary (main-server or wshcmd-connserver)
- 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
- Initialize StreamBroker at the same place RpcClient is assigned
- Add a startup health check asserting broker readiness before serving requests
- Sequence initialization: broker first, then accept file commands
- Document broker requirement wherever wshfs is embedded
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
- static files not available before app initialization; use Ap
- reading file: %w
- no pending stream (call PrepareConnect first)
- failed to set rwnd size: %w
- no route id available
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/66df9f7246bcbedb.
Report an issue: GitHub.