router-for-me/CLIProxyAPI · error

invalid log offset

Error message

invalid log offset

What it means

Returned by readCompleteLogLines (logs.go:1083) when the starting offset is negative. The function reads only whole lines from a byte offset within the log file; a negative offset has no meaning for io.NewSectionReader and is rejected up front before the file is even opened.

Source

Thrown at internal/api/handlers/management/logs.go:1083

			if _, errWrite := dst.Write(buf[:n]); errWrite != nil {
				return errWrite
			}
			pos += int64(n)
			remaining -= int64(n)
		}
		if errRead != nil {
			if errRead == io.EOF && remaining == 0 {
				return nil
			}
			return errRead
		}
	}
	return nil
}

func readCompleteLogLines(path string, offset, maxOffset int64, limit int) (completeLogRead, error) {
	if offset < 0 {
		return completeLogRead{}, fmt.Errorf("invalid log offset")
	}
	file, errOpen := os.Open(path)
	if errOpen != nil {
		return completeLogRead{}, errOpen
	}
	defer func() {
		_ = file.Close()
	}()
	info, errStat := file.Stat()
	if errStat != nil {
		return completeLogRead{}, errStat
	}
	if info.IsDir() {
		return completeLogRead{}, fmt.Errorf("invalid log file")
	}
	size := info.Size()
	if maxOffset < 0 || maxOffset > size {
		maxOffset = size

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Check how the offset was computed; clamp it to 0 before calling: if offset < 0 { offset = 0 }
  2. If it came from a cursor, discard the cursor and start a fresh read
  3. Add an assertion/log at the call site that produced the negative value to find the arithmetic bug

Example fix

// before
read, err := readCompleteLogLines(path, lastEnd-chunkSize, -1, limit)

// after
start := lastEnd - chunkSize
if start < 0 {
	start = 0
}
read, err := readCompleteLogLines(path, start, -1, limit)
Defensive patterns

Strategy: validation

Validate before calling

if offset < 0 {
	offset = 0
}
read, err := readCompleteLogLines(path, offset, -1, limit)

Prevention

When it happens

Trigger: A continuation request whose decoded cursor carries a negative Offset (validateLogCursor normally blocks this earlier, so this fires when internal callers or tests pass a negative start); programmatic misuse of the reader with a computed offset that underflowed.

Common situations: Client code computing start = lastEnd - delta where delta > lastEnd; corrupted or hand-edited cursor tokens that bypassed earlier validation layers.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/8f960211614592b1. Report an issue: GitHub.