{"record":{"id":"a9e25dc719bd1322","repo":"valyala/fasthttp","slug":"must-implement-seek","errorCode":null,"errorMessage":"must implement seek","messagePattern":"must implement seek","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fs.go","lineNumber":760,"sourceCode":"}\n\nfunc (ff *fsFile) decReadersCount() {\n\tff.h.cacheManager.DecReadersCount(ff)\n}\n\n// bigFileReader attempts to trigger sendfile\n// for sending big files over the wire.\ntype bigFileReader struct {\n\tf  fs.File\n\tff *fsFile\n\tr  io.Reader\n\tlr io.LimitedReader\n}\n\nfunc (r *bigFileReader) UpdateByteRange(startPos, endPos int) error {\n\tseeker, ok := r.f.(io.Seeker)\n\tif !ok {\n\t\treturn errors.New(\"must implement seek\")\n\t}\n\tif _, err := seeker.Seek(int64(startPos), io.SeekStart); err != nil {\n\t\treturn err\n\t}\n\tr.r = &r.lr\n\tr.lr.R = r.f\n\tr.lr.N = int64(endPos - startPos + 1)\n\treturn nil\n}\n\nfunc (r *bigFileReader) Read(p []byte) (int, error) {\n\treturn r.r.Read(p)\n}\n\nfunc (r *bigFileReader) WriteTo(w io.Writer) (int64, error) {\n\tif rf, ok := w.(io.ReaderFrom); ok {\n\t\t// fast path. Send file must be triggered\n\t\treturn rf.ReadFrom(r.r)","sourceCodeStart":742,"sourceCodeEnd":778,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/fs.go#L742-L778","documentation":"bigFileReader.UpdateByteRange requires the underlying file handle to implement io.Seeker; if it doesn't (e.g. wrapped reader or unusual fs handle) it returns this error. Byte-range serving for large files depends on seeking directly in the file.","triggerScenarios":"Calling bigFileReader.UpdateByteRange (used by fasthttp's Range request handling for large files) when r.f was created from something that doesn't implement io.Seeker — for instance a custom FileSystem returning a non-seekable file wrapper.","commonSituations":"Custom fasthttp FS implementations returning os.File wrappers stripped of Seek; embedding the file in a network stream or compressed reader; mocking fs.File in tests with a type lacking Seek.","solutions":["Ensure the FileSystem returns *os.File (or another io.ReadSeeker) for large files","Wrap the custom file type and implement io.Seeker (delegate to the real file)","Fall back to small-file range handling (which uses memory) or serve the full file if seeking is impossible","Fix test mocks to embed a Seeker implementation"],"exampleFix":"// before\ntype myFile struct{ r io.Reader }\nfs := &fasthttp.FS{ ... } // returns myFile -> UpdateByteRange fails\n// after\ntype myFile struct{ f *os.File }\nfunc (m *myFile) Seek(offset int64, whence int) (int64, error) {\n    return m.f.Seek(offset, whence)\n}","handlingStrategy":"type-guard","validationCode":"if _, ok := file.(io.Seeker); !ok {\n    return errors.New(\"file for bigFileReader must implement io.Seeker\")\n}","typeGuard":"func isSeekable(f fs.File) bool {\n    _, ok := f.(io.Seeker)\n    return ok\n}","tryCatchPattern":"if err := r.UpdateByteRange(start, end); err != nil && err.Error() == \"must implement seek\" {\n    // fall back to full-file serving or buffered reader\n}","preventionTips":["Return *os.File from custom FileSystem implementations","Implement io.Seeker on any fs.File wrapper","Test range requests against your custom FS","Fall back to memory-based range handling for non-seekable sources"],"tags":["fasthttp","filesystem","range-requests","seeker"],"backgroundTag":"seek-not-supported","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}