wavetermdev/waveterm · error
failed to set rwnd size: %w
Error message
failed to set rwnd size: %w
What it means
After a successful attach, StartStream applies the receiver-window size negotiated in pendingStreamMeta via StreamManager.SetRwndSize. This error wraps any failure from that call. It indicates the stream is attached but flow-control configuration could not be applied, so the stream is left partially initialized.
Source
Thrown at pkg/jobmanager/jobmanager.go:371
func (jm *JobManager) StartStream(msc *MainServerConn) error {
jm.lock.Lock()
defer jm.lock.Unlock()
if jm.Cmd == nil {
return fmt.Errorf("job not started")
}
if jm.pendingStreamMeta == nil {
return fmt.Errorf("no pending stream (call PrepareConnect first)")
}
err := msc.WshRpc.StreamBroker.AttachStreamWriter(jm.pendingStreamMeta, jm.StreamManager)
if err != nil {
return fmt.Errorf("failed to attach stream writer: %w", err)
}
err = jm.StreamManager.SetRwndSize(int(jm.pendingStreamMeta.RWnd))
if err != nil {
return fmt.Errorf("failed to set rwnd size: %w", err)
}
log.Printf("StartStream: streamid=%s rwnd=%d streaming started\n", jm.pendingStreamMeta.Id, jm.pendingStreamMeta.RWnd)
jm.pendingStreamMeta = nil
return nil
}
func MakeJobDomainSocket(clientId string, jobId string) error {
socketDir := filepath.Join("/tmp", fmt.Sprintf("waveterm-%d", os.Getuid()))
err := os.MkdirAll(socketDir, 0700)
if err != nil {
return fmt.Errorf("failed to create socket directory: %w", err)
}
socketPath := wavebase.GetRemoteJobSocketPath(jobId)
os.Remove(socketPath)
View on GitHub (pinned to a4447c1563)
Solutions
- Log jm.pendingStreamMeta.RWnd and the wrapped error to see whether the negotiated value is sane
- Validate RWnd is > 0 (and within protocol bounds) before calling StartStream; re-run PrepareConnect if not
- Re-do the PrepareConnect/StartStream cycle to renegotiate a fresh window size
- Check StreamManager initialization order so SetRwndSize runs on a ready stream
Example fix
// before
jm.StartStream() // trusts pendingStreamMeta.RWnd
// after
if jm.pendingStreamMeta == nil || jm.pendingStreamMeta.RWnd == 0 {
return fmt.Errorf("invalid rwnd negotiated, re-run PrepareConnect")
}
if err := jm.StartStream(); err != nil {
return err
} Defensive patterns
Strategy: validation
Validate before calling
if jm.pendingStreamMeta == nil || jm.pendingStreamMeta.RWnd == 0 {
return fmt.Errorf("invalid stream metadata/rwnd, re-run PrepareConnect")
} Type guard
func validPendingStream(jm *JobManager) bool {
return jm.pendingStreamMeta != nil && jm.pendingStreamMeta.RWnd > 0
} Try / catch
if err := jm.StartStream(); err != nil {
if strings.HasPrefix(err.Error(), "failed to set rwnd size") {
log.Printf("rwnd error: %v", errors.Unwrap(err))
// renegotiate and retry
if perr := jm.PrepareConnect(); perr == nil {
err = jm.StartStream()
}
}
return err
} Prevention
- Validate the negotiated RWnd value before starting the stream
- Re-run the PrepareConnect/StartStream pair on any partial-initialization error
- Check StreamManager initialization order in setup code
- Watch for platform int-width issues when converting RWnd
When it happens
Trigger: SetRwndSize returns an error — typically an invalid, zero, or out-of-range RWnd value in pendingStreamMeta, or the StreamManager rejecting the resize for an attached/invalid stream state.
Common situations: Peer negotiated a bad RWnd value during PrepareConnect; integer overflow/widening issue in int(jm.pendingStreamMeta.RWnd); StreamManager not fully initialized before StartStream; version skew where window-size semantics changed.
Related errors
- reading file: %w
- invalid rwnd size: %d
- no pending stream (call PrepareConnect first)
- stream broker not available
- starting remote file stream: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/ed5978ec3d043dc9.
Report an issue: GitHub.