wavetermdev/waveterm · error
appending to file: %w
Error message
appending to file: %w
What it means
When the 8KB batch buffer fills during 'wsh file append', each batch is sent via wshclient.FileAppendCommand; a failure there is wrapped as 'appending to file: %w'. This is a mid-stream RPC failure, so earlier 8KB batches may already have been written — the file can end up partially appended.
Source
Thrown at cmd/wsh/cmd/wshcmd-file.go:307
n, err := reader.Read(chunk)
if err == io.EOF {
break
}
if err != nil {
return fmt.Errorf("reading input: %w", err)
}
if int64(buf.Len()+n) > remainingSpace {
return fmt.Errorf("append would exceed maximum file size of %d bytes", MaxFileSize)
}
buf.Write(chunk[:n])
if buf.Len() >= 8192 { // 8KB batch size
fileData.Data64 = base64.StdEncoding.EncodeToString(buf.Bytes())
err = wshclient.FileAppendCommand(RpcClient, fileData, &wshrpc.RpcOpts{Timeout: fileTimeout})
if err != nil {
return fmt.Errorf("appending to file: %w", err)
}
remainingSpace -= int64(buf.Len())
buf.Reset()
}
}
if buf.Len() > 0 {
fileData.Data64 = base64.StdEncoding.EncodeToString(buf.Bytes())
err = wshclient.FileAppendCommand(RpcClient, fileData, &wshrpc.RpcOpts{Timeout: fileTimeout})
if err != nil {
return fmt.Errorf("appending to file: %w", err)
}
}
return nil
}
func checkFileSize(path string, maxSize int64) (*wshrpc.FileInfo, error) {View on GitHub (pinned to a4447c1563)
Solutions
- Retry the append for the remaining data (already-written batches persist; skip or resume accordingly)
- Increase the RPC timeout for large appends on slow links
- Verify block connectivity and remote disk space before long appends
- Write to a local temp file and send one 'wsh file write' instead of many RPC round-trips
Example fix
// before
err = wshclient.FileAppendCommand(RpcClient, fileData, &wshrpc.RpcOpts{Timeout: fileTimeout})
if err != nil {
return fmt.Errorf("appending to file: %w", err)
}
// after
err = wshclient.FileAppendCommand(RpcClient, fileData, &wshrpc.RpcOpts{Timeout: fileTimeout})
if err != nil {
return fmt.Errorf("appending %d-byte batch (offset %d, earlier batches kept): %w", buf.Len(), sentSoFar, err)
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: ensure block reachable and remote has headroom
info, err := wshclient.FileInfoCommand(RpcClient, fileData, &wshrpc.RpcOpts{Timeout: fileTimeout})
if err != nil { return err }
if info.Size+expectedInputSize > 10*1024*1024 { return errors.New("no headroom") } Type guard
func isRetryable(err error) bool {
return errors.Is(err, context.DeadlineExceeded) || errors.Is(err, io.ErrUnexpectedEOF)
} Try / catch
for attempt := 0; attempt < 3; attempt++ {
err = wshclient.FileAppendCommand(RpcClient, fileData, &wshrpc.RpcOpts{Timeout: fileTimeout})
if err == nil { break }
if !isRetryable(err) { return fmt.Errorf("appending to file: %w", err) }
time.Sleep(time.Duration(1<<attempt) * time.Second)
} Prevention
- Retry transient RPC failures with backoff on batch flushes
- Track how many bytes were flushed so retries can resume, not duplicate
- Increase timeout for multi-MB appends over slow links
- Monitor remote disk space for long append jobs
When it happens
Trigger: A FileAppendCommand RPC error mid-loop: timeout (fileTimeout) on a slow connection, disconnection from the target block, or a server-side write error (permissions, disk full) after at least one successful batch.
Common situations: Appending multi-MB streams over a slow/unstable connection where a later batch times out; remote disk filling up during the append; the target block being closed while the stream is in flight.
Related errors
- failed to list workspaces: %v
- failed to list blocks from all %d workspace(s)
- delete block failed: %v
- opening config file: %w
- running view command: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/9476aaac60d6191d.
Report an issue: GitHub.