can1357/oh-my-pi · error · ArchiveError
Remote archive range request failed (HTTP ${response.status}
Error message
Remote archive range request failed (HTTP ${response.status}) What it means
The ByteSource returned by httpByteSource() fulfills each read(start, end) with a ranged GET expecting a 206 Partial Content response. This throw fires when a later range read returns any other status — the server that supported the probe may have started rejecting requests, or per-request auth/URL problems surfaced mid-stream. The response body is cancelled before throwing.
Source
Thrown at packages/utils/src/ar/source.ts:127
}
await probe.body?.cancel();
// `Content-Range: bytes 0-0/12345` carries the total size.
const contentRange = probe.headers.get("content-range");
const total = contentRange ? Number(/\/(\d+)$/.exec(contentRange)?.[1]) : Number.NaN;
if (!Number.isSafeInteger(total) || total < 0) {
throw new ArchiveError("Remote archive did not report a valid size in Content-Range");
}
return {
size: total,
async read(start, end) {
assertValidRange(start, end);
if (start === end) return new Uint8Array(0);
const response = await doFetch(url, {
headers: { ...options.headers, range: `bytes=${start}-${end - 1}` },
});
if (response.status !== 206) {
await response.body?.cancel();
throw new ArchiveError(`Remote archive range request failed (HTTP ${response.status})`);
}
const bytes = new Uint8Array(await response.arrayBuffer());
if (bytes.byteLength !== end - start) {
throw new ArchiveError("Invalid archive: truncated data");
}
return bytes;
},
};
}
/** Options for {@link cachingByteSource}. */
export interface CachingByteSourceOptions {
/** Cache block size in bytes. Default 256 KiB. */
blockSize?: number;
/** Max cached blocks. Default 64 (16 MiB at the default block size). */
maxBlocks?: number;
}
View on GitHub (pinned to 9690622007)
Solutions
- Implement retry with fresh credentials/URL for each read — re-create httpByteSource with a newly signed URL when reads start failing
- Add a retry wrapper around read() with backoff for 429/5xx statuses
- Reduce concurrent range reads (or wrap with cachingByteSource) to avoid rate limiting
- Fall back to downloading the whole archive to disk (fileByteSource) when the remote is unstable
Example fix
// before: single long-lived source dies when the presigned URL expires
const src = await httpByteSource(signedUrl);
await src.read(0, 512); // ... later 403
// after: refresh the URL per read session
async function readRange(url, start, end) {
const src = await httpByteSource(await refreshSignedUrl(url));
return src.read(start, end);
} Defensive patterns
Strategy: retry
Try / catch
async function readResilient(src, start, end, attempts = 3) {
for (let i = 0; ; i++) {
try {
return await src.read(start, end);
} catch (err) {
if (i >= attempts || !(err instanceof ArchiveError) || !/HTTP \d+/.test(err.message)) throw err;
await Bun.sleep(2 ** i * 250);
}
}
} Prevention
- Use long-lived credentials or re-sign URLs per read for slow extractions
- Wrap every remote read in bounded retry with backoff for 429/5xx
- Wrap the source in cachingByteSource to reduce the number of HTTP range requests
- Monitor extraction jobs and re-create httpByteSource when repeated non-206 statuses appear
When it happens
Trigger: Any ByteSource.read(start, end) on the httpByteSource source where the ranged fetch returns non-206: presigned URL expired between probe and read (403), the object was deleted mid-session (404), rate limiting (429), transient 5xx, or a proxy that forwards the initial request but rejects subsequent ranged ones.
Common situations: Long-running extraction sessions over expiring S3 presigned URLs; load balancers routing reads to servers lacking the object; throttling under many concurrent small range reads; CDN misconfiguration that caches the probe but 4xx's range requests.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Remote archive is too large to buffer without range support
- Remote archive request failed (HTTP ${probe.status})
- Remote archive did not report a valid size in Content-Range
- V2 remote compaction failed (${response.status} ${response.s
- sso-role
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/687dfed1d90b5466.
Report an issue: GitHub.