{"record":{"id":"53d2e3c2931e00e0","repo":"wavetermdev/waveterm","slug":"file-info-is-required","errorCode":null,"errorMessage":"file info is required","messagePattern":"file info is required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/wsh/cmd/wshcmd-file-util.go","lineNumber":99,"sourceCode":"\t\tappendData := fileData\n\t\tappendData.Data64 = base64.StdEncoding.EncodeToString(chunk)\n\n\t\terr = wshclient.FileAppendCommand(RpcClient, appendData, &wshrpc.RpcOpts{Timeout: int64(fileTimeout)})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"appending chunk to file: %w\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc streamReadFromFile(ctx context.Context, fileData wshrpc.FileData, writer io.Writer) error {\n\tbroker := RpcClient.StreamBroker\n\tif broker == nil {\n\t\treturn fmt.Errorf(\"stream broker not available\")\n\t}\n\tif fileData.Info == nil {\n\t\treturn fmt.Errorf(\"file info is required\")\n\t}\n\treaderRouteId := RpcClientRouteId\n\tif readerRouteId == \"\" {\n\t\treturn fmt.Errorf(\"no route id available\")\n\t}\n\tconn, err := connparse.ParseURI(fileData.Info.Path)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing file path: %w\", err)\n\t}\n\twriterRouteId := wshutil.MakeConnectionRouteId(conn.Host)\n\treader, streamMeta := broker.CreateStreamReader(readerRouteId, writerRouteId, 256*1024)\n\tdefer reader.Close()\n\tgo func() {\n\t\t<-ctx.Done()\n\t\treader.Close()\n\t}()\n\tdata := wshrpc.CommandFileStreamData{\n\t\tInfo:       fileData.Info,","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/cmd/wsh/cmd/wshcmd-file-util.go#L81-L117","documentation":"streamReadFromFile in cmd/wsh/cmd/wshcmd-file-util.go requires the FileData to carry a populated Info pointer, because the streaming path needs Info.Path to parse the connection URI and to send to the remote FileStreamCommand. The wsh CLI throws this error when a caller passes FileData with Info == nil.","triggerScenarios":"Calling streamReadFromFile (via `wsh file cat`) with a wshrpc.FileData whose Info field was never allocated, e.g. FileData{Info: nil} or FileData{} constructed programmatically instead of from CLI args.","commonSituations":"Custom builds or forks of wsh that construct FileData directly (e.g. from a config value that is empty), or refactors that changed fileCatRun's path handling so the FileInfo literal is skipped when path is empty.","solutions":["Ensure FileData.Info is initialized: FileData{Info: &wshrpc.FileInfo{Path: path}} before calling streamReadFromFile.","If path may be empty, fail early with a clear message before building FileData.","Check the calling code (fileCatRun) still populates Info after any refactor; add a nil-check guard upstream."],"exampleFix":"// before\nfileData := wshrpc.FileData{}\nerr = streamReadFromFile(ctx, fileData, os.Stdout)\n// after\nfileData := wshrpc.FileData{Info: &wshrpc.FileInfo{Path: path}}\nerr = streamReadFromFile(ctx, fileData, os.Stdout)","handlingStrategy":"validation","validationCode":"if fileData.Info == nil {\n    return fmt.Errorf(\"cannot stream file: FileData.Info must be set with a Path\")\n}\nerr := streamReadFromFile(ctx, fileData, os.Stdout)","typeGuard":"func hasFileInfo(fd wshrpc.FileData) bool { return fd.Info != nil && fd.Info.Path != \"\" }","tryCatchPattern":"if err := streamReadFromFile(ctx, fileData, w); err != nil {\n    if strings.Contains(err.Error(), \"file info is required\") {\n        // caller bug: FileData built without Info — fix construction\n    }\n    return err\n}","preventionTips":["Always construct FileData with a non-nil Info: wshrpc.FileData{Info: &wshrpc.FileInfo{Path: path}}.","Add an upstream nil-check on Info before any stream helper call.","After refactors, assert FileData construction sites still populate Info."],"tags":["go","wsh","file-stream","nil-pointer"],"backgroundTag":"missing-required-argument","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}