wavetermdev/waveterm · error

invalid rwnd size: %d

Error message

invalid rwnd size: %d

What it means

connectToStreamHelper_withlock reads streamMeta.RWnd (receive window size) as an int and rejects negative values before connecting the stream client. The error indicates the client sent a negative RWnd, which is meaningless for flow control.

Source

Thrown at pkg/jobmanager/jobmanager.go:171

	}
}

func (jm *JobManager) GetJobAuthInfo() (string, string) {
	jm.lock.Lock()
	defer jm.lock.Unlock()
	return jm.JobId, jm.JobAuthToken
}

func (jm *JobManager) IsJobStarted() bool {
	jm.lock.Lock()
	defer jm.lock.Unlock()
	return jm.Cmd != nil
}

func (jm *JobManager) connectToStreamHelper_withlock(mainServerConn *MainServerConn, streamMeta wshrpc.StreamMeta, seq int64) (int64, error) {
	rwndSize := int(streamMeta.RWnd)
	if rwndSize < 0 {
		return 0, fmt.Errorf("invalid rwnd size: %d", rwndSize)
	}

	if jm.connectedStreamClient != nil {
		log.Printf("connectToStreamHelper: disconnecting existing client\n")
		oldStreamId := jm.StreamManager.GetStreamId()
		jm.StreamManager.ClientDisconnected()
		if oldStreamId != "" {
			mainServerConn.WshRpc.StreamBroker.DetachStreamWriter(oldStreamId)
			log.Printf("connectToStreamHelper: detached old stream id=%s\n", oldStreamId)
		}
		jm.connectedStreamClient = nil
	}
	dataSender := &routedDataSender{
		wshRpc: mainServerConn.WshRpc,
		route:  streamMeta.ReaderRouteId,
	}
	serverSeq, err := jm.StreamManager.ClientConnected(
		streamMeta.Id,

View on GitHub (pinned to a4447c1563)

Solutions

  1. Fix the caller to send a non-negative RWnd (use the protocol's default size constant instead of -1)
  2. Validate RWnd on the client before building StreamMeta and clamp to a sensible minimum (e.g. 4096)
  3. Omit StreamMeta entirely if the caller does not intend to stream, rather than sending a bogus RWnd
  4. Check for signed/unsigned conversion bugs (int32 -> int64) that produce negatives

Example fix

// before
meta := wshrpc.StreamMeta{Id: id, RWnd: -1}
// after
const DefaultRWnd = 8192
rwnd := DefaultRWnd
meta := wshrpc.StreamMeta{Id: id, RWnd: rwnd}
Defensive patterns

Strategy: validation

Validate before calling

if streamMeta.RWnd < 0 {
    return fmt.Errorf("RWnd must be >= 0, got %d; use the default size instead", streamMeta.RWnd)
}

Prevention

When it happens

Trigger: A StartJob or PrepareConnect request whose StreamMeta.RWnd is negative (e.g. -1 used as a 'default' sentinel by a buggy client, or integer underflow when computing the window size).

Common situations: Client code initializing RWnd to -1 or 0 minus a value by mistake; version mismatch where one side encodes RWnd differently; manual JSON construction of StreamMeta with a wrong field.

Related errors


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