{"record":{"id":"7e36f50f113b7d3a","repo":"wavetermdev/waveterm","slug":"appending-chunk-to-file-w","errorCode":null,"errorMessage":"appending chunk to file: %w","messagePattern":"appending chunk to file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/wsh/cmd/wshcmd-file-util.go","lineNumber":86,"sourceCode":"\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"reading input: %w\", err)\n\t\t}\n\n\t\t// Check total size\n\t\ttotalWritten += int64(n)\n\t\tif totalWritten > MaxFileSize {\n\t\t\treturn fmt.Errorf(\"input exceeds maximum file size of %d bytes\", MaxFileSize)\n\t\t}\n\n\t\t// Prepare and send chunk\n\t\tchunk := buf[:n]\n\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}","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/cmd/wsh/cmd/wshcmd-file-util.go#L68-L104","documentation":"After each 32KB chunk read, streamWriteToFile sends it via FileAppendCommand. A failure on any chunk mid-stream is wrapped as \"appending chunk to file\", meaning the destination file was truncated and only partially written.","triggerScenarios":"FileAppendCommand fails partway through streaming: RPC timeout (fileTimeout) on a slow link, connection drop mid-transfer, or server-side write failure (disk full, permission revoked).","commonSituations":"Transferring a large file over a flaky SSH/remote connection; disk quota exceeded on the remote host mid-write; network hiccup after several minutes of transfer.","solutions":["Retry the whole streaming command — the file is re-truncated at the start of each attempt, avoiding partial data.","Check free disk space/quota on the destination host.","Increase fileTimeout for high-latency connections.","For large/unreliable transfers, use resumable tools (rsync over ssh) instead of wsh streaming."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-check destination capacity if accessible\nif df, err := exec.Command(\"sh\", \"-c\", \"df -k $(dirname \"+path+\")\").Output(); err == nil {\n    // abort early if low disk space\n}","typeGuard":null,"tryCatchPattern":"err := streamWriteToFile(fileData, reader)\nfor retries := 0; err != nil && retries < 3; retries++ {\n    time.Sleep(time.Duration(1<<retries) * time.Second) // restart re-truncates file\n    err = streamWriteToFile(fileData, reader)\n}","preventionTips":["Retry whole transfers — each attempt truncates cleanly","Monitor remote disk space/quota before large streams","Increase fileTimeout on slow or flaky links","Use resumable tools (rsync) for very large transfers"],"tags":["streaming","rpc","network"],"backgroundTag":"rpc-call-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}