wavetermdev/waveterm · info · ErrBOF
beginning of file
Error message
beginning of file
What it means
ErrBOF ("beginning of file") is a sentinel error in the logview multibuf package. Backward-scanning APIs (PrevLinePtr, Move, PrevLine) return it when the caller asks to move before offset 0 of the file, i.e. there is no earlier line to read. It is a normal, expected signal — not a failure — that the scan has hit the start of the file.
Source
Thrown at pkg/util/logview/multibuf.go:20
// SPDX-License-Identifier: Apache-2.0
package logview
import (
"errors"
"io"
"os"
)
type MultiBufferByteGetter struct {
File *os.File
Offset int64
EOF bool
Buffers [][]byte
BufSize int64
}
var ErrBOF = errors.New("beginning of file")
func MakeMultiBufferByteGetter(file *os.File, bufSize int64) *MultiBufferByteGetter {
return &MultiBufferByteGetter{
File: file,
Offset: 0,
EOF: false,
Buffers: [][]byte{},
BufSize: bufSize,
}
}
func (mb *MultiBufferByteGetter) readFromBuffer(offset int64) (byte, bool) {
if offset < mb.Offset || offset >= mb.Offset+int64(mb.bufSize()) {
return 0, false
}
bufIdx := int((offset - mb.Offset) / mb.BufSize)
bufOffset := (offset - mb.Offset) % mb.BufSize
return mb.Buffers[bufIdx][bufOffset], trueView on GitHub (pinned to a4447c1563)
Solutions
- Check for errors.Is(err, logview.ErrBOF) after each backward step and treat it as the stop condition of your scan loop, not as a failure.
- Clamp or validate the target offset before calling Move/PrevLinePtr so it never goes below 0.
- Ensure the *os.File passed to MakeMultiBufferByteGetter is valid and opened for reading so offsets behave as expected.
Example fix
// before
line, err := mb.PrevLinePtr(off)
if err != nil {
return err
}
// after
line, err := mb.PrevLinePtr(off)
if errors.Is(err, logview.ErrBOF) {
return nil // reached start of file; stop scanning
}
if err != nil {
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
if targetOffset < 0 {
// skip backward scan; already at start of file
} Type guard
func isBOF(err error) bool { return errors.Is(err, logview.ErrBOF) } Try / catch
line, err := mb.PrevLinePtr(off)
if errors.Is(err, logview.ErrBOF) {
return io.EOF // normalize to standard end/edge-of-input signal
}
if err != nil {
return err
} Prevention
- Always treat ErrBOF as a loop-termination signal when scanning backwards.
- Clamp offsets to [0, fileSize) before calling Move/PrevLinePtr.
- Use errors.Is, never ==, for sentinel comparison.
When it happens
Trigger: Calling PrevLinePtr/PrevLine repeatedly until the iterator is already at offset 0, or calling Move with a negative target offset below 0 on a MultiBufferByteGetter reading a log file.
Common situations: Tail/grep-style log viewers that page backwards through a log and read past the first line; scanning a small file where the requested lookback window exceeds the file size.
Related errors
- procinfo: process not found
- failed to copy from file: %v
- no window found with workspace ${data.workspaceid}
- missing zone file info for ${zoneId}:${fileName}
- integer overflow
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/a96d8ca82147cba3.
Report an issue: GitHub.