{"record":{"id":"cd6010300ec68710","repo":"cloudreve/cloudreve","slug":"invalid-range-failed-to-overlap","errorCode":null,"errorMessage":"invalid range: failed to overlap","messagePattern":"invalid range: failed to overlap","errorType":"http","errorClass":null,"httpStatus":416,"severity":"warning","filePath":"pkg/filemanager/manager/entitysource/entitysource.go","lineNumber":49,"sourceCode":"\t\"github.com/cloudreve/Cloudreve/v4/pkg/setting\"\n\t\"github.com/cloudreve/Cloudreve/v4/pkg/util\"\n\t\"github.com/juju/ratelimit\"\n)\n\nconst (\n\tshortSeekBytes = 1024\n\t// The algorithm uses at most sniffLen bytes to make its decision.\n\tsniffLen         = 512\n\tdefaultUrlExpire = time.Hour * 1\n)\n\nvar (\n\t// ErrNoContentLength is returned by Seek when the initial http response did not include a Content-Length header\n\tErrNoContentLength = errors.New(\"Content-Length was not set\")\n\n\t// errNoOverlap is returned by serveContent's parseRange if first-byte-pos of\n\t// all of the byte-range-spec values is greater than the content size.\n\terrNoOverlap = errors.New(\"invalid range: failed to overlap\")\n)\n\ntype EntitySource interface {\n\tio.ReadSeekCloser\n\tio.ReaderAt\n\n\t// Url generates a download url for the entity.\n\tUrl(ctx context.Context, opts ...EntitySourceOption) (*EntityUrl, error)\n\t// Serve serves the entity to the client, with supports on Range header and If- cache control.\n\tServe(w http.ResponseWriter, r *http.Request, opts ...EntitySourceOption)\n\t// Entity returns the entity of the source.\n\tEntity() fs.Entity\n\t// IsLocal returns true if the source is in local machine.\n\tIsLocal() bool\n\t// LocalPath returns the local path of the source file.\n\tLocalPath(ctx context.Context) string\n\t// Apply applies the options to the source.\n\tApply(opts ...EntitySourceOption)","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/cloudreve/cloudreve/blob/20c95ad73f3a8bcb72887fea91ff31ab24fa1011/pkg/filemanager/manager/entitysource/entitysource.go#L31-L67","documentation":"OneDrive driver Thumb converts a failed GetThumbURL into this wrapped error when OneDrive answers that no thumbnail exists for the file — either the sentinel ErrThumbSizeNotFound or a *RespError with APIError.Code == itemNotFound (onedrive.go:139-150). It marks an expected capability gap, not an outage. Note the fall-through bug: any other error type is silently dropped and the function returns (\"\", nil), hiding real failures.","triggerScenarios":"Requesting thumbnails for file types Graph cannot render (some RAW images, exotic formats, huge videos); files above OneDrive's thumbnail size limits; freshly uploaded content whose thumbnail has not been processed yet.","commonSituations":"Enabling OneDrive thumbnail proxy for broad extension lists; large media libraries where many files have no server-side preview.","solutions":["Treat as expected: fall back to local thumbnail generation for these files","Restrict the policy's ThumbExts to formats OneDrive handles (jpg/png/pdf and friends)","If nothing gets thumbnails anymore, verify the actual error — the current fall-through swallows non-itemNotFound errors","Cache the negative result so repeated requests don't re-hit Graph"],"exampleFix":"// before\nres, err := handler.client.GetThumbURL(ctx, e.Source())\nif err != nil {\n\tvar apiErr *RespError\n\tif errors.As(err, &apiErr); err == ErrThumbSizeNotFound || (apiErr != nil && apiErr.APIError.Code == notFoundError) {\n\t\treturn \"\", fmt.Errorf(\"thumb not supported in OneDrive: %w\", err)\n\t}\n}\nreturn res, nil\n\n// after — also stop swallowing unexpected errors\nres, err := handler.client.GetThumbURL(ctx, e.Source())\nif err != nil {\n\tvar apiErr *RespError\n\tif err == ErrThumbSizeNotFound || (errors.As(err, &apiErr) && apiErr.APIError.Code == notFoundError) {\n\t\treturn \"\", fmt.Errorf(\"thumb not supported in OneDrive: %w\", err)\n\t}\n\treturn \"\", err\n}\nreturn res, nil","handlingStrategy":"fallback","validationCode":"// Skip the remote call for extensions OneDrive cannot thumbnail\nvar odThumbExts = map[string]bool{\".jpg\": true, \".jpeg\": true, \".png\": true, \".pdf\": true, \".bmp\": true, \".gif\": true}\nif !odThumbExts[strings.ToLower(path.Ext(e.Source()))] {\n\treturn \"\", driver.ErrThumbUnsupported // triggers local generation fallback\n}","typeGuard":"func isThumbUnsupported(err error) bool {\n\tif err == ErrThumbSizeNotFound {\n\t\treturn true\n\t}\n\tvar re *RespError\n\treturn errors.As(err, &re) && re.APIError.Code == \"itemNotFound\"\n}","tryCatchPattern":"res, err := handler.client.GetThumbURL(ctx, e.Source())\nif err != nil {\n\tif isThumbUnsupported(err) {\n\t\t// expected for this file type: fall back to local thumbnail generation\n\t\t// or serve a placeholder icon; never fail the file listing\n\t}\n\treturn \"\", err // fix the fall-through that currently swallows other errors\n}","preventionTips":["Configure ThumbExts conservatively for OneDrive policies","Cache negative thumbnail results per file","Regression-test the error branch so unexpected API errors stop being swallowed"],"tags":["onedrive","thumbnail","microsoft-graph","capability"],"backgroundTag":null,"analyzedSha":"20c95ad73f3a8bcb72887fea91ff31ab24fa1011","analyzedAt":"2026-08-16T01:42:55.403Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}