{"record":{"id":"b89bc3154130f592","repo":"AlistGo/alist","slug":"open-download-file-failed-w","errorCode":null,"errorMessage":"open download file failed: %w","messagePattern":"open download file failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/halalcloud/driver.go","lineNumber":260,"sourceCode":"\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\taddressDuration = sliceAddress.ExpireAt\n\t\t\tfileAddrs = append(fileAddrs, sliceAddress.Addresses...)\n\t\t\tstartIndex = endIndex\n\t\t\tnodesIndex -= 200\n\t\t}\n\n\t}\n\n\tsize := result.FileSize\n\tchunks := getChunkSizes(result.Sizes)\n\tresultRangeReader := func(ctx context.Context, httpRange http_range.Range) (io.ReadCloser, error) {\n\t\tlength := httpRange.Length\n\t\tif httpRange.Length >= 0 && httpRange.Start+httpRange.Length >= size {\n\t\t\tlength = -1\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"open download file failed: %w\", err)\n\t\t}\n\t\too := &openObject{\n\t\t\tctx:     ctx,\n\t\t\td:       fileAddrs,\n\t\t\tchunk:   &[]byte{},\n\t\t\tchunks:  &chunks,\n\t\t\tskip:    httpRange.Start,\n\t\t\tsha:     result.Sha1,\n\t\t\tshaTemp: sha1.New(),\n\t\t}\n\n\t\treturn readers.NewLimitedReadCloser(oo, length), nil\n\t}\n\n\tvar duration time.Duration\n\tif addressDuration != 0 {\n\t\tduration = time.Until(time.UnixMilli(addressDuration))\n\t} else {","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/halalcloud/driver.go#L242-L278","documentation":"Returned inside the range-reader closure of HalalCloud's file-open path. Inspection of the region shows a defect: `err` at this point is a leftover variable from an earlier scope (the code just computed `length` from httpRange/size), so the check `if err != nil` can only fire if a stale outer err is non-nil, wrapping it with %w. In a correctly scoped version this guard is meant to surface a range/parameter error before constructing openObject.","triggerScenarios":"Opening a HalalCloud download with a byte range when an earlier operation in the same function (e.g. metadata/result fetch) left err non-nil; reading files whose reported FileSize disagrees with the chunk map in result.Sizes.","commonSituations":"Range requests (video seeking, resumable downloads) against files whose chunk layout changed server-side after the file handle was opened; driver version where the stale-err scoping bug is present, making previously-cleared errors resurface at open time.","solutions":["Upgrade the driver if the stale-err bug is fixed upstream — the guard should test the range parameters, not a leftover err.","Retry the open: re-fetch the file metadata (result) so err starts nil, then issue the range read.","If reproducing consistently for one file, re-upload / re-hash the file — a corrupt chunk map makes size/range math invalid.","As a local patch, restructure so length computation errors are captured into a fresh error variable inside the closure."],"exampleFix":"// before (bug: wraps stale outer err)\nif err != nil {\n    return nil, fmt.Errorf(\"open download file failed: %w\", err)\n}\n\n// after: validate the range inputs themselves\nif httpRange.Start < 0 || (size > 0 && httpRange.Start >= size) {\n    return nil, fmt.Errorf(\"open download file failed: invalid range start %d for size %d\", httpRange.Start, size)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"r, err := link.Get(ctx, rangeHdr)\nif err != nil {\n    if strings.Contains(err.Error(), \"open download file failed\") {\n        // stale metadata is the usual cause: re-open once with fresh result\n        r, err = link.Get(ctx, rangeHdr)\n    }\n    if err != nil { return err }\n}","preventionTips":["Keep driver updated to pick up the stale-err scoping fix","Re-fetch file metadata before issuing ranges on long-lived handles","Avoid reusing handles after the underlying file changed"],"tags":["halalcloud","range-request","stale-variable","download"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}