wavetermdev/waveterm · error

reading file stream: %w

Error message

reading file stream: %w

What it means

After the remote file stream starts successfully, Read drains the stream with io.ReadAll(reader). If the stream itself breaks mid-transfer (connection drop, reader closed via context cancellation, protocol error), io.ReadAll fails and Read wraps it with this message. The stream started, so this is a mid-transfer failure, not a start failure.

Source

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

	}()
	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,
		ByteRange:  byteRange,
		StreamMeta: *streamMeta,
	}
	fileInfo, err := wshclient.RemoteFileStreamCommand(RpcClient, remoteData, &wshrpc.RpcOpts{Route: writerRouteId})
	if err != nil {
		return nil, fmt.Errorf("starting remote file stream: %w", err)
	}
	var rawData []byte
	if fileInfo != nil && !fileInfo.IsDir {
		rawData, err = io.ReadAll(reader)
		if err != nil {
			return nil, fmt.Errorf("reading file stream: %w", err)
		}
	}
	rtnData := &wshrpc.FileData{Info: fileInfo}
	if len(rawData) > 0 {
		rtnData.Data64 = base64.StdEncoding.EncodeToString(rawData)
	}
	return rtnData, nil
}

func GetConnectionRouteId(ctx context.Context, path string) (string, error) {
	conn, err := parseConnection(ctx, path)
	if err != nil {
		return "", err
	}
	return wshutil.MakeConnectionRouteId(conn.Host), nil
}

func FileStream(ctx context.Context, data wshrpc.CommandFileStreamData) (*wshrpc.FileInfo, error) {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check whether the context was cancelled/timed out — wrap Read with an adequate timeout
  2. Retry the Read; transient network drops are often resolved on retry
  3. For large files, use FileStream with byte ranges to transfer in resumable chunks
  4. Investigate connection stability (SSH keepalives) if it recurs

Example fix

// before
ctx := context.Background()
data, err := wshfs.Read(ctx, fd) // no timeout; hangs then breaks on flaky link
// after
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
data, err := wshfs.Read(ctx, fd)
Defensive patterns

Strategy: retry

Validate before calling

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel() // ensure adequate timeout before starting the transfer

Try / catch

out, err := wshfs.Read(ctx, data)
if err != nil {
    if strings.Contains(err.Error(), "reading file stream") && ctx.Err() == nil {
        return retryWithBackoff(3, func() (*wshrpc.FileData, error) { return wshfs.Read(ctx, data) }) // transient stream break
    }
    return nil, err
}

Prevention

When it happens

Trigger: The underlying connection drops while transferring file bytes; the context passed to Read is cancelled causing reader.Close(); the remote writer terminates the stream prematurely (e.g. remote process killed); chunk framing error in the stream broker.

Common situations: Reading a large file over a flaky SSH link; user cancels the operation (ctx cancelled) and the code reports this error; laptop network change mid-transfer; remote host reboot.

Related errors


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