{"record":{"id":"6bf77fee1312cfba","repo":"wavetermdev/waveterm","slug":"reading-file-stream-w","errorCode":null,"errorMessage":"reading file stream: %w","messagePattern":"reading file stream: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/fileshare/wshfs/wshfs.go","lineNumber":84,"sourceCode":"\t}()\n\tbyteRange := \"\"\n\tif data.At != nil && data.At.Size > 0 {\n\t\tbyteRange = fmt.Sprintf(\"%d-%d\", data.At.Offset, data.At.Offset+int64(data.At.Size)-1)\n\t}\n\tremoteData := wshrpc.CommandRemoteFileStreamData{\n\t\tPath:       conn.Path,\n\t\tByteRange:  byteRange,\n\t\tStreamMeta: *streamMeta,\n\t}\n\tfileInfo, err := wshclient.RemoteFileStreamCommand(RpcClient, remoteData, &wshrpc.RpcOpts{Route: writerRouteId})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"starting remote file stream: %w\", err)\n\t}\n\tvar rawData []byte\n\tif fileInfo != nil && !fileInfo.IsDir {\n\t\trawData, err = io.ReadAll(reader)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"reading file stream: %w\", err)\n\t\t}\n\t}\n\trtnData := &wshrpc.FileData{Info: fileInfo}\n\tif len(rawData) > 0 {\n\t\trtnData.Data64 = base64.StdEncoding.EncodeToString(rawData)\n\t}\n\treturn rtnData, nil\n}\n\nfunc GetConnectionRouteId(ctx context.Context, path string) (string, error) {\n\tconn, err := parseConnection(ctx, path)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn wshutil.MakeConnectionRouteId(conn.Host), nil\n}\n\nfunc FileStream(ctx context.Context, data wshrpc.CommandFileStreamData) (*wshrpc.FileInfo, error) {","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/remote/fileshare/wshfs/wshfs.go#L66-L102","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check whether the context was cancelled/timed out — wrap Read with an adequate timeout","Retry the Read; transient network drops are often resolved on retry","For large files, use FileStream with byte ranges to transfer in resumable chunks","Investigate connection stability (SSH keepalives) if it recurs"],"exampleFix":"// before\nctx := context.Background()\ndata, err := wshfs.Read(ctx, fd) // no timeout; hangs then breaks on flaky link\n// after\nctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)\ndefer cancel()\ndata, err := wshfs.Read(ctx, fd)","handlingStrategy":"retry","validationCode":"ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)\ndefer cancel() // ensure adequate timeout before starting the transfer","typeGuard":null,"tryCatchPattern":"out, err := wshfs.Read(ctx, data)\nif err != nil {\n    if strings.Contains(err.Error(), \"reading file stream\") && ctx.Err() == nil {\n        return retryWithBackoff(3, func() (*wshrpc.FileData, error) { return wshfs.Read(ctx, data) }) // transient stream break\n    }\n    return nil, err\n}","preventionTips":["Give Read a generous timeout for large files; avoid cancelling ctx mid-transfer","Prefer chunked reads via byte ranges for big files to limit blast radius","Monitor connection stability (SSH keepalives, network changes)","Log wrapped io errors to distinguish cancellation from network failure"],"tags":["go","io","network","streaming"],"backgroundTag":"stream-read-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}