{"record":{"id":"128adfd38a12af7e","repo":"wavetermdev/waveterm","slug":"error-appending-to-blockfile-w","errorCode":null,"errorMessage":"error appending to blockfile: %w","messagePattern":"error appending to blockfile: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/blockcontroller/blockcontroller.go","lineNumber":374,"sourceCode":"}\n\nfunc getTermSize(bdata *waveobj.Block) waveobj.TermSize {\n\tif bdata.RuntimeOpts != nil {\n\t\treturn bdata.RuntimeOpts.TermSize\n\t} else {\n\t\treturn waveobj.TermSize{\n\t\t\tRows: 25,\n\t\t\tCols: 80,\n\t\t}\n\t}\n}\n\nfunc HandleAppendBlockFile(blockId string, blockFile string, data []byte) error {\n\tctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)\n\tdefer cancelFn()\n\terr := filestore.WFS.AppendData(ctx, blockId, blockFile, data)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error appending to blockfile: %w\", err)\n\t}\n\twps.Broker.Publish(wps.WaveEvent{\n\t\tEvent: wps.Event_BlockFile,\n\t\tScopes: []string{\n\t\t\twaveobj.MakeORef(waveobj.OType_Block, blockId).String(),\n\t\t},\n\t\tData: &wps.WSFileEventData{\n\t\t\tZoneId:   blockId,\n\t\t\tFileName: blockFile,\n\t\t\tFileOp:   wps.FileOp_Append,\n\t\t\tData64:   base64.StdEncoding.EncodeToString(data),\n\t\t},\n\t})\n\treturn nil\n}\n\nfunc HandleTruncateBlockFile(blockId string) error {\n\tctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/blockcontroller/blockcontroller.go#L356-L392","documentation":"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.","triggerScenarios":"WFS.AppendData returning an error: block directory not initialized in filestore, underlying file locked/corrupt, disk full, or context timeout (DefaultTimeout) exceeded.","commonSituations":"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.","solutions":["Read the wrapped cause to distinguish not-exist vs IO errors; recreate the block file via ResyncController or by restarting the block","Check available disk space and file permissions under the wave filestore directory","Increase handling if writes are timing out — reduce output volume or check filestore backend health","Reset the terminal state (truncate) if the file is corrupt, then retry"],"exampleFix":"// before\nerr := filestore.WFS.AppendData(ctx, blockId, blockFile, data)\n// ignore/drop output on error\n// after\nif err := filestore.WFS.AppendData(ctx, blockId, blockFile, data); err != nil {\n    log.Printf(\"dropping output for %s: %v\", blockId, err)\n}","handlingStrategy":"try-catch","validationCode":"// ensure block filestore initialized\nif _, err := filestore.WFS.StatFile(ctx, blockId, blockFile); err != nil { /* init via resync */ }","typeGuard":null,"tryCatchPattern":"if err := HandleAppendBlockFile(blockId, file, data); err != nil {\n    if !errors.Is(err, context.DeadlineExceeded) {\n        log.Printf(\"append failed: %v\", err)\n    }\n}","preventionTips":["Monitor disk space on the filestore volume","Recreate block files after crashes rather than appending blindly","Handle block cleanup events to stop writes to removed blocks"],"tags":["filestore","io","terminal"],"backgroundTag":"file-write-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}