{"record":{"id":"7e5d727ae8b12cea","repo":"wavetermdev/waveterm","slug":"lineptr-is-nil","errorCode":null,"errorMessage":"linePtr is nil","messagePattern":"linePtr is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/util/logview/logview.go","lineNumber":86,"sourceCode":"\t\treturn linePtr, nil\n\t}\n\treturn lv.NextLinePtr(linePtr)\n}\n\nfunc (lv *LogView) isLineMatch(offset int64) bool {\n\tif lv.MatchRe == nil {\n\t\treturn true\n\t}\n\tlineData, err := lv.readLineAt(offset)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn lv.MatchRe.Match(lineData)\n}\n\nfunc (lv *LogView) NextLinePtr(linePtr *LinePtr) (*LinePtr, error) {\n\tif linePtr == nil {\n\t\treturn nil, fmt.Errorf(\"linePtr is nil\")\n\t}\n\tnumLines := int64(0)\n\toffset := linePtr.Offset\n\tfor {\n\t\tvar err error\n\t\tnextOffset, err := lv.MultiBuf.NextLine(offset)\n\t\tif err == io.EOF {\n\t\t\treturn nil, nil\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnumLines++\n\t\tif lv.isLineMatch(nextOffset) {\n\t\t\treturn &LinePtr{Offset: nextOffset, RealLineNum: linePtr.RealLineNum + numLines, LineNum: linePtr.LineNum + 1}, nil\n\t\t}\n\t\toffset = nextOffset\n\t}","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/util/logview/logview.go#L68-L104","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Initialize the cursor with FirstLinePtr (or LastLinePtr) before calling NextLinePtr.","Check the error return of any earlier call that produced the LinePtr and do not use a nil result.","Guard call sites with a nil check on the *LinePtr before navigation.","If restoring persisted state, validate the line pointer exists before use and fall back to FirstLinePtr."],"exampleFix":"// before\nnext, err := lv.NextLinePtr(cur)\n// after\nif cur == nil {\n    cur, err = lv.FirstLinePtr()\n    if err != nil { return err }\n}\nnext, err := lv.NextLinePtr(cur)","handlingStrategy":"validation","validationCode":"func safeNext(lv *logview.LogView, cur *logview.LinePtr) (*logview.LinePtr, error) {\n    var err error\n    if cur == nil {\n        cur, err = lv.FirstLinePtr()\n        if err != nil { return nil, err }\n    }\n    return lv.NextLinePtr(cur)\n}","typeGuard":"func hasLinePtr(p *logview.LinePtr) bool { return p != nil }","tryCatchPattern":"next, err := lv.NextLinePtr(cur)\nif err != nil {\n    if strings.Contains(err.Error(), \"linePtr is nil\") {\n        cur, err = lv.FirstLinePtr()\n        if err != nil { return err }\n        next, err = lv.NextLinePtr(cur)\n    }\n    if err != nil { return err }\n}","preventionTips":["Always initialize navigation state with FirstLinePtr/LastLinePtr before relative moves.","Check error returns of every call that yields a *LinePtr; never propagate a nil result.","Nil-check cursor fields in UI handlers before calling Move.","Validate deserialized/persisted view state contains a non-nil LinePtr before use."],"tags":["nil-pointer","validation","logview","go"],"backgroundTag":"nil-pointer-argument","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}