wavetermdev/waveterm · error

error appending to blockfile: %w

Error message

error appending to blockfile: %w

What it means

HandleAppendBlockFile writes terminal output data to a block's file via filestore.WFS.AppendData. Any storage-layer failure (IO error, missing blockdir, disk full) is wrapped as 'error appending to blockfile: %w'. The event publish to wps only happens if the append succeeds.

Source

Thrown at pkg/blockcontroller/blockcontroller.go:374

}

func getTermSize(bdata *waveobj.Block) waveobj.TermSize {
	if bdata.RuntimeOpts != nil {
		return bdata.RuntimeOpts.TermSize
	} else {
		return waveobj.TermSize{
			Rows: 25,
			Cols: 80,
		}
	}
}

func HandleAppendBlockFile(blockId string, blockFile string, data []byte) error {
	ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)
	defer cancelFn()
	err := filestore.WFS.AppendData(ctx, blockId, blockFile, data)
	if err != nil {
		return fmt.Errorf("error appending to blockfile: %w", err)
	}
	wps.Broker.Publish(wps.WaveEvent{
		Event: wps.Event_BlockFile,
		Scopes: []string{
			waveobj.MakeORef(waveobj.OType_Block, blockId).String(),
		},
		Data: &wps.WSFileEventData{
			ZoneId:   blockId,
			FileName: blockFile,
			FileOp:   wps.FileOp_Append,
			Data64:   base64.StdEncoding.EncodeToString(data),
		},
	})
	return nil
}

func HandleTruncateBlockFile(blockId string) error {
	ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Read the wrapped cause to distinguish not-exist vs IO errors; recreate the block file via ResyncController or by restarting the block
  2. Check available disk space and file permissions under the wave filestore directory
  3. Increase handling if writes are timing out — reduce output volume or check filestore backend health
  4. Reset the terminal state (truncate) if the file is corrupt, then retry

Example fix

// before
err := filestore.WFS.AppendData(ctx, blockId, blockFile, data)
// ignore/drop output on error
// after
if err := filestore.WFS.AppendData(ctx, blockId, blockFile, data); err != nil {
    log.Printf("dropping output for %s: %v", blockId, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure block filestore initialized
if _, err := filestore.WFS.StatFile(ctx, blockId, blockFile); err != nil { /* init via resync */ }

Try / catch

if err := HandleAppendBlockFile(blockId, file, data); err != nil {
    if !errors.Is(err, context.DeadlineExceeded) {
        log.Printf("append failed: %v", err)
    }
}

Prevention

When it happens

Trigger: WFS.AppendData returning an error: block directory not initialized in filestore, underlying file locked/corrupt, disk full, or context timeout (DefaultTimeout) exceeded.

Common situations: Terminal output arriving after the block's filestore was cleaned up; disk quota exceeded on the machine storing wave files; corrupted filestore cache; very large writes timing out.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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