{"record":{"id":"0d4ba993d7b9ffa9","repo":"wavetermdev/waveterm","slug":"reading-file-w-0d4ba9","errorCode":null,"errorMessage":"reading file: %w","messagePattern":"reading file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/wsh/cmd/wshcmd-wavepath.go","lineNumber":114,"sourceCode":"\t\treturn fmt.Errorf(\"getting file stats: %w\", err)\n\t}\n\n\t// Read last 16KB or whole file if smaller\n\treadSize := int64(16 * 1024)\n\tvar offset int64\n\tif stat.Size() > readSize {\n\t\toffset = stat.Size() - readSize\n\t}\n\n\t_, err = file.Seek(offset, 0)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"seeking file: %w\", err)\n\t}\n\n\tbuf := make([]byte, readSize)\n\tn, err := file.Read(buf)\n\tif err != nil && err != io.EOF {\n\t\treturn fmt.Errorf(\"reading file: %w\", err)\n\t}\n\tbuf = buf[:n]\n\n\t// Skip partial line at start if we're not at beginning of file\n\tif offset > 0 {\n\t\tidx := bytes.IndexByte(buf, '\\n')\n\t\tif idx >= 0 {\n\t\t\tbuf = buf[idx+1:]\n\t\t}\n\t}\n\n\t// Split into lines\n\tlines := bytes.Split(buf, []byte{'\\n'})\n\n\t// Take last 100 lines if we have more\n\tstartIdx := 0\n\tif len(lines) > 100 {\n\t\tstartIdx = len(lines) - 100","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/cmd/wsh/cmd/wshcmd-wavepath.go#L96-L132","documentation":"After seeking, tailLogFile's Read on the log file returned a non-EOF error, so it cannot deliver the buffered tail of the log. EOF is deliberately tolerated since Read at EOF is expected for small files.","triggerScenarios":"`wsh wavepath log --tail` when the underlying file disappears mid-read (rotation/delete), hardware or network I/O error, or interruption while reading from an unstable mount.","commonSituations":"Log rotation racing the read, disks dropping errors, or reading logs over SSHFS/NFS mounts that time out.","solutions":["Re-run the command; rotation races are transient.","Check `dmesg`/system logs for disk I/O errors.","Move logs to a local disk instead of a network mount.","Use `wsh wavepath log` (no --tail) and tail with system tools."],"exampleFix":"// before\nn, err := file.Read(buf)\nif err != nil && err != io.EOF { return fmt.Errorf(\"reading file: %w\", err) }\n// after\nn, err := io.ReadFull(file, buf)\nif err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { return fmt.Errorf(\"reading file: %w\", err) }","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"n, err := file.Read(buf)\nif err != nil && err != io.EOF {\n    if isTransient(err) { return retryTail(path) }\n    return fmt.Errorf(\"reading file: %w\", err)\n}","preventionTips":["Avoid racing log rotation with the tail read.","Keep logs off unreliable network mounts.","Retry once on transient I/O errors before surfacing."],"tags":["filesystem","file-io","read"],"backgroundTag":"file-read-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}