fix(docs): correct off-by-one and comment in Range request example#28031
fix(docs): correct off-by-one and comment in Range request example#28031
Conversation
The HTTP Range header uses inclusive end bounds, but Blob.slice() uses
exclusive end, so `end + 1` is needed. Also fix the split comment to
show the actual output of headers.get("Range").split("=").
Closes #28030
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Updated 12:33 AM PT - Mar 12th, 2026
✅ Your commit d1050ab has passed in 🧪 To try this PR locally: bunx bun-pr 28031That installs a local version of the PR into your bun-28031 --bun |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughUpdate to the documentation example that changes how the HTTP Range header is parsed: the header tokenization now uses the last "=" segment, derives start/end from strings, defaults start to Changes
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/runtime/http/routing.mdx`:
- Around line 222-231: The Range parsing currently turns an open-ended end token
into 0 because Number("") === 0; fix the parsing in the Range handling by
extracting the raw end token (e.g. from
req.headers.get("Range").split("=").at(-1).split("-")), set end to Infinity if
the raw end token is empty, otherwise convert it with Number(rawEnd), and only
add 1 when constructing the slice end when an explicit end was supplied; update
the call that returns the file slice (bigFile.slice) to use undefined or omit
the +1 adjustment for open-ended ranges so bigFile.slice(start, end+1) is only
used when end is a real number.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 56f93c13-f1a8-46be-b3f1-3322d850d00b
📒 Files selected for processing (1)
docs/runtime/http/routing.mdx
There was a problem hiding this comment.
LGTM — both the comment fix and the slice off-by-one correction are clearly right.
Extended reasoning...
Overview
This PR modifies a single documentation file (docs/runtime/http/routing.mdx) with two small fixes to a Range request code example: (1) correcting a misleading inline comment about what .split("=") produces, and (2) fixing an off-by-one error by changing bigFile.slice(start, end) to bigFile.slice(start, end + 1) since HTTP Range headers are end-inclusive but Blob.slice() is end-exclusive.
Security risks
None. This is a documentation-only change with no runtime code modifications.
Level of scrutiny
Minimal scrutiny needed — this is a two-line docs fix with straightforward, verifiable correctness. req.headers.get("Range") returns the header value (e.g., "bytes=0-100"), so splitting on = yields ["bytes", "0-100"], not ["Range: bytes", "0-100"]. And Blob.slice() follows the standard end-exclusive convention, so end + 1 is needed to include the byte at the end index.
Other factors
The build passes. No outstanding reviewer comments. The PR description includes a clear test plan verifying both fixes. No bugs were found by the automated bug hunting system.
Avoid Number("") === 0 bug for open-ended ranges like "bytes=100-"
by keeping start/end as strings until after checking for empty end
token. Only applies +1 inclusive-to-exclusive adjustment when an
explicit end was provided; otherwise passes undefined to slice().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Found 4 issues this PR may fix:
🤖 Generated with Claude Code |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/runtime/http/routing.mdx`:
- Around line 222-230: The Range parsing sample in the req.headers.get("Range")
block fails for suffix ranges like "bytes=-500"; update the logic around
startStr, endStr, start and end to special-case when startStr === "" (suffix
range) and compute start as contentLength - Number(endStr) (clamped to >=0) and
set end to contentLength (or undefined for slicing semantics), otherwise
continue treating startStr as the numeric start; alternatively, if you don't
want to support suffix ranges, add a clear comment in the snippet stating it
only supports "bytes=<start>-" or "bytes=<start>-<end>" forms.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8b242c70-984c-411f-bc84-5ac409380c35
📒 Files selected for processing (1)
docs/runtime/http/routing.mdx
docs/runtime/http/routing.mdx
Outdated
| const [startStr = "0", endStr] = req.headers | ||
| .get("Range") // "bytes=0-100" | ||
| .split("=") // ["bytes", "0-100"] | ||
| .at(-1) // "0-100" | ||
| .split("-") // ["0", "100"] | ||
| .map(Number); // [0, 100] | ||
| .split("-"); // ["0", "100"] | ||
|
|
||
| const start = Number(startStr); | ||
| // Range end is inclusive, but slice() end is exclusive | ||
| const end = endStr ? Number(endStr) + 1 : undefined; |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Does the HTTP Rangeheader support suffix byte ranges likebytes=-500, and what bytes should the server return for that request?
💡 Result:
Yes. HTTP byte-range requests support suffix byte ranges of the form bytes=-N. bytes=-500 means “return the last 500 bytes of the selected representation”. (ietf.org)
If the representation length is L bytes, the server should return the bytes with inclusive offsets:
- start = max(L − 500, 0)
- end = L − 1
So:
- if
L ≥ 500: return bytesL-500throughL-1(the final 500 bytes) - if
L < 500: return the entire representation (ietf.org)
When the range is satisfiable and the server honors it, the response is typically 206 Partial Content with a Content-Range indicating the selected range. (rfcinfo.com)
Citations:
- 1: https://www.ietf.org/ietf-ftp/rfc/rfc9110.html
- 2: https://www.ietf.org/ietf-ftp/rfc/rfc9110.html
- 3: https://rfcinfo.com/rfc-9110/14
🏁 Script executed:
# Check the actual content of the file at the specified lines
sed -n '222,230p' docs/runtime/http/routing.mdxRepository: oven-sh/bun
Length of output: 394
Handle suffix byte ranges per RFC 9110 or narrow the example's scope.
The code doesn't handle suffix byte ranges like bytes=-500 (which should return the last 500 bytes per RFC 9110). When parsing bytes=-500, split("-") yields ["", "500"], so startStr becomes an empty string. Number("") evaluates to 0, resulting in slice(0, 501) and incorrectly returning the first 501 bytes instead of the last 500. Either special-case startStr === "" to handle suffix ranges, or explicitly document that this snippet only supports bytes=<start>- or bytes=<start>-<end> forms.
🛠️ Possible fix
const [startStr = "0", endStr] = req.headers
.get("Range") // "bytes=0-100"
.split("=") // ["bytes", "0-100"]
.at(-1) // "0-100"
.split("-"); // ["0", "100"]
+ // `bytes=-500` means "last 500 bytes"
+ const bigFile = Bun.file("./big-video.mp4");
+ if (startStr === "") {
+ return new Response(bigFile.slice(-Number(endStr)));
+ }
+
const start = Number(startStr);
// Range end is inclusive, but slice() end is exclusive
const end = endStr ? Number(endStr) + 1 : undefined;
- // return a slice of the file
- const bigFile = Bun.file("./big-video.mp4");
+ // return a slice of the file
return new Response(bigFile.slice(start, end));🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/runtime/http/routing.mdx` around lines 222 - 230, The Range parsing
sample in the req.headers.get("Range") block fails for suffix ranges like
"bytes=-500"; update the logic around startStr, endStr, start and end to
special-case when startStr === "" (suffix range) and compute start as
contentLength - Number(endStr) (clamped to >=0) and set end to contentLength (or
undefined for slicing semantics), otherwise continue treating startStr as the
numeric start; alternatively, if you don't want to support suffix ranges, add a
clear comment in the snippet stating it only supports "bytes=<start>-" or
"bytes=<start>-<end>" forms.
Add comment noting the snippet supports "bytes=N-M" and "bytes=N-" forms, not suffix ranges like "bytes=-500". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
LGTM — straightforward docs fix correcting an off-by-one error and a misleading comment in the Range request example.
Extended reasoning...
Overview
This PR modifies a single documentation file (docs/runtime/http/routing.mdx) to fix two issues in a code example showing HTTP Range request handling: (1) correcting an inaccurate inline comment about what .split("=") produces, and (2) fixing an off-by-one error where Blob.slice() needs end + 1 since HTTP Range headers use inclusive end bytes while slice() uses exclusive end. It also properly handles open-ended ranges (e.g., bytes=100-) by checking if endStr is truthy before adding 1, which was addressed after CodeRabbit feedback.
Security risks
None. This is a documentation-only change with no runtime code modifications.
Level of scrutiny
Low scrutiny is appropriate. This is a small, self-contained documentation fix. The code example corrections are verifiably correct: "bytes=0-100".split("=") does produce ["bytes", "0-100"], and Blob.slice() is indeed end-exclusive while HTTP Range headers are end-inclusive.
Other factors
CodeRabbit raised a valid concern about open-ended Range headers, which was addressed in the follow-up commit (f7e3bcd). That inline comment is now marked as resolved. No outstanding reviewer comments remain. The changes are minimal, correct, and improve the accuracy of the documentation.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/runtime/http/routing.mdx`:
- Around line 221-226: The snippet that parses the Range header calls
req.headers.get("Range") and immediately chains .split, which throws when the
header is absent; update the code around the Range parsing (the expression that
produces startStr and endStr from req.headers.get("Range")) to first guard for a
missing header (e.g., const range = req.headers.get("Range"); if (!range) { /*
return 200/handle full response or document requirement */ } ), then perform the
split on range (or provide a safe default like "0-") so startStr/endStr parsing
never runs on null; alternatively explicitly document that the example requires
the Range header be present.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 111594c5-7c7c-4c12-bc1f-7c17f1e4893b
📒 Files selected for processing (1)
docs/runtime/http/routing.mdx
Return the full file when the Range header is absent, avoiding a TypeError from chaining .split() on null. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
LGTM — straightforward docs fix correcting an off-by-one and a misleading comment in the Range request example.
Extended reasoning...
Overview
This PR modifies a single documentation file (docs/runtime/http/routing.mdx) to fix two issues in a Range request code example: (1) a wrong inline comment claiming .split("=") produces ["Range: bytes", "0-100"] when it actually produces ["bytes", "0-100"], and (2) an off-by-one bug where slice(start, end) was used directly with the inclusive Range end value instead of slice(start, end + 1). The fix also properly handles open-ended ranges (bytes=N-) by conditionally passing undefined as the slice end.
Security risks
None. This is a documentation-only change with no runtime code modifications.
Level of scrutiny
Low scrutiny is appropriate. This is a small, self-contained fix to a code example in documentation. The logic is straightforward and correct — HTTP Range headers use inclusive end bounds while Blob.slice() uses exclusive end bounds, so +1 is the right adjustment. The open-ended range handling (endStr ? Number(endStr) + 1 : undefined) is also correct.
Other factors
CodeRabbit raised a valid point about suffix byte ranges (bytes=-500) not being handled, but the PR explicitly scopes the example to bytes=N-M and bytes=N- forms via a comment, which is reasonable for a documentation snippet. The first CodeRabbit issue (open-ended ranges) was addressed in a follow-up commit. CI passes. No outstanding reviewer comments requiring action.
There was a problem hiding this comment.
LGTM — straightforward docs fix correcting the Range request example.
Extended reasoning...
Overview
This PR modifies a single documentation file (docs/runtime/http/routing.mdx) to fix an incorrect Range request code example. The changes correct an off-by-one error (HTTP Range headers are end-inclusive but Blob.slice() is end-exclusive), fix a misleading inline comment, add a null guard for when the Range header is absent, and properly handle open-ended ranges (bytes=N-).
Security risks
None. This is a documentation-only change with no impact on runtime code, build artifacts, or any executable paths.
Level of scrutiny
Low scrutiny is appropriate. This is a small, self-contained fix to a code example in documentation. The corrections are factually verifiable (Number("") === 0, slice() is end-exclusive, .split("=") on "bytes=0-100" yields ["bytes", "0-100"]). The build passes and CodeRabbit found no remaining actionable issues.
Other factors
The PR went through multiple iterations addressing CodeRabbit feedback (open-ended range handling, missing header guard), all of which were resolved. There is one unresolved CodeRabbit comment about suffix byte ranges (bytes=-500), but this is a nice-to-have edge case for a documentation example, not a correctness bug in the changes made. The final code is clear, well-commented, and more correct than the original.
Summary
end + 1inBlob.slice()since HTTP Range headers are end-inclusive butslice()is end-exclusive.split("=")on"bytes=0-100"produces["bytes", "0-100"], not["Range: bytes", "0-100"]Closes #28030
Test plan
Blob.slice()is end-exclusive:new Blob(["0123456789"]).slice(0, 4).text()returns"0123"(4 bytes).split("=")output:"bytes=0-100".split("=")returns["bytes", "0-100"]🤖 Generated with Claude Code