{"record":{"id":"8f960211614592b1","repo":"router-for-me/CLIProxyAPI","slug":"invalid-log-offset","errorCode":null,"errorMessage":"invalid log offset","messagePattern":"invalid log offset","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"internal/api/handlers/management/logs.go","lineNumber":1083,"sourceCode":"\t\t\tif _, errWrite := dst.Write(buf[:n]); errWrite != nil {\n\t\t\t\treturn errWrite\n\t\t\t}\n\t\t\tpos += int64(n)\n\t\t\tremaining -= int64(n)\n\t\t}\n\t\tif errRead != nil {\n\t\t\tif errRead == io.EOF && remaining == 0 {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn errRead\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc readCompleteLogLines(path string, offset, maxOffset int64, limit int) (completeLogRead, error) {\n\tif offset < 0 {\n\t\treturn completeLogRead{}, fmt.Errorf(\"invalid log offset\")\n\t}\n\tfile, errOpen := os.Open(path)\n\tif errOpen != nil {\n\t\treturn completeLogRead{}, errOpen\n\t}\n\tdefer func() {\n\t\t_ = file.Close()\n\t}()\n\tinfo, errStat := file.Stat()\n\tif errStat != nil {\n\t\treturn completeLogRead{}, errStat\n\t}\n\tif info.IsDir() {\n\t\treturn completeLogRead{}, fmt.Errorf(\"invalid log file\")\n\t}\n\tsize := info.Size()\n\tif maxOffset < 0 || maxOffset > size {\n\t\tmaxOffset = size","sourceCodeStart":1065,"sourceCodeEnd":1101,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/api/handlers/management/logs.go#L1065-L1101","documentation":"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.","triggerScenarios":"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.","commonSituations":"Client code computing start = lastEnd - delta where delta > lastEnd; corrupted or hand-edited cursor tokens that bypassed earlier validation layers.","solutions":["Check how the offset was computed; clamp it to 0 before calling: if offset < 0 { offset = 0 }","If it came from a cursor, discard the cursor and start a fresh read","Add an assertion/log at the call site that produced the negative value to find the arithmetic bug"],"exampleFix":"// before\nread, err := readCompleteLogLines(path, lastEnd-chunkSize, -1, limit)\n\n// after\nstart := lastEnd - chunkSize\nif start < 0 {\n\tstart = 0\n}\nread, err := readCompleteLogLines(path, start, -1, limit)","handlingStrategy":"validation","validationCode":"if offset < 0 {\n\toffset = 0\n}\nread, err := readCompleteLogLines(path, offset, -1, limit)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never compute offsets by subtraction without clamping at 0","Log the inputs at call sites that derive offsets from previous responses"],"tags":["logs","offset","validation","internal-api"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}