wavetermdev/waveterm · error

linePtr is nil

Error message

linePtr is nil

What it means

LogView.NextLinePtr advances a line pointer to the next line in the log view's MultiBuf. It requires a non-nil starting *LinePtr so it knows the offset to search from; passing nil is a programming error by the caller, so it returns this error instead of panicking on a nil dereference.

Source

Thrown at pkg/util/logview/logview.go:86

		return linePtr, nil
	}
	return lv.NextLinePtr(linePtr)
}

func (lv *LogView) isLineMatch(offset int64) bool {
	if lv.MatchRe == nil {
		return true
	}
	lineData, err := lv.readLineAt(offset)
	if err != nil {
		return false
	}
	return lv.MatchRe.Match(lineData)
}

func (lv *LogView) NextLinePtr(linePtr *LinePtr) (*LinePtr, error) {
	if linePtr == nil {
		return nil, fmt.Errorf("linePtr is nil")
	}
	numLines := int64(0)
	offset := linePtr.Offset
	for {
		var err error
		nextOffset, err := lv.MultiBuf.NextLine(offset)
		if err == io.EOF {
			return nil, nil
		}
		if err != nil {
			return nil, err
		}
		numLines++
		if lv.isLineMatch(nextOffset) {
			return &LinePtr{Offset: nextOffset, RealLineNum: linePtr.RealLineNum + numLines, LineNum: linePtr.LineNum + 1}, nil
		}
		offset = nextOffset
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Initialize the cursor with FirstLinePtr (or LastLinePtr) before calling NextLinePtr.
  2. Check the error return of any earlier call that produced the LinePtr and do not use a nil result.
  3. Guard call sites with a nil check on the *LinePtr before navigation.
  4. If restoring persisted state, validate the line pointer exists before use and fall back to FirstLinePtr.

Example fix

// before
next, err := lv.NextLinePtr(cur)
// after
if cur == nil {
    cur, err = lv.FirstLinePtr()
    if err != nil { return err }
}
next, err := lv.NextLinePtr(cur)
Defensive patterns

Strategy: validation

Validate before calling

func safeNext(lv *logview.LogView, cur *logview.LinePtr) (*logview.LinePtr, error) {
    var err error
    if cur == nil {
        cur, err = lv.FirstLinePtr()
        if err != nil { return nil, err }
    }
    return lv.NextLinePtr(cur)
}

Type guard

func hasLinePtr(p *logview.LinePtr) bool { return p != nil }

Try / catch

next, err := lv.NextLinePtr(cur)
if err != nil {
    if strings.Contains(err.Error(), "linePtr is nil") {
        cur, err = lv.FirstLinePtr()
        if err != nil { return err }
        next, err = lv.NextLinePtr(cur)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling NextLinePtr(nil) directly, or calling a wrapper (FirstLinePtr, Move, LastLinePtr, ReadWindow call paths) that passes an uninitialized/zeroed pointer variable, or propagating a nil LinePtr returned from an earlier failed call without checking it.

Common situations: A caller stored the result of FirstLinePtr/Move in a variable that stayed nil after an earlier error; a struct field holding the current cursor was never initialized before the first navigation; JSON-deserialized view state had a missing/empty linePtr.

Related errors


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