DIYgod/RSSHub · warning · InvalidParameterError
unsupported range: ${typ}
Error message
unsupported range: ${typ} What it means
parseRange parses an HTTP Range header and only supports the 'bytes' range unit (RFC 7233). If the token before '=' is anything other than 'bytes' (or the header is malformed so the split yields a different unit), it throws InvalidParameterError with the offending unit.
Source
Thrown at lib/routes/telegram/channel-media.ts:121
}
);
for await (const chunk of chunks) {
if (skip >= chunk.length) {
skip -= chunk.length;
continue;
}
yield skip ? chunk.subarray(skip) : chunk;
skip = 0;
}
}
function parseRange(range: string, length: bigInt.BigInteger) {
if (!range) {
return [];
}
const [typ, segstr] = range.split('=', 2);
if (typ !== 'bytes') {
throw new InvalidParameterError(`unsupported range: ${typ}`);
}
const segs = segstr.split(',').map((s) => s.trim());
const parsedSegs: bigInt.BigInteger[][] = [];
for (const seg of segs) {
const range = seg
.split('-', 2)
.filter((v) => !!v)
.map((v) => bigInt(v));
if (range.length < 2) {
if (seg.startsWith('-')) {
range.unshift(bigInt(0));
} else {
range.push(length.subtract(bigInt(1)));
}
}
parsedSegs.push(range);
}
return parsedSegs;View on GitHub (pinned to bed535e087)
Solutions
- Have the client send a standards-compliant 'Range: bytes=start-end' header.
- In parseRange, treat an unknown unit as 'no range' (return []) and serve the full content with 200 instead of throwing, if partial content is optional.
- If a non-bytes unit is genuinely needed, extend parseRange to handle it explicitly rather than relying on the throw.
Example fix
// before
const [typ, segstr] = range.split('=', 2);
if (typ !== 'bytes') {
throw new InvalidParameterError(`unsupported range: ${typ}`);
}
// after: ignore unsupported units and serve full content
const [typ, segstr] = range.split('=', 2);
if (typ !== 'bytes') {
return []; // caller treats empty as 'no range'
} Defensive patterns
Strategy: validation
Validate before calling
function isBytesRange(range: string | undefined): boolean {
return !range || range.toLowerCase().startsWith('bytes=');
}
// reject/ignore the request early if the client sent a non-bytes range Type guard
function isBytesRangeHeader(range: string | undefined): boolean {
return !range || range.trim().toLowerCase().startsWith('bytes=');
} Try / catch
try {
const segs = parseRange(rangeHeader, length);
// serve partial or full content based on segs
} catch (e) {
if (e instanceof InvalidParameterError && /unsupported range/.test(e.message)) {
// ignore the unsupported Range and serve the full content with 200
return fullContent();
}
throw e;
} Prevention
- Only emit 'Range: bytes=...' from clients (the only unit parseRange supports).
- Treat an unsupported range unit as 'no range' rather than an error when partial content is optional.
- Validate the header at the HTTP layer before it reaches parseRange.
When it happens
Trigger: A client (media player, browser, downloader) sends a Range header like 'items=0-100', 'time=0-5', or a malformed 'range=0-100'. The split('=') yields a unit that is not 'bytes'.
Common situations: A custom downloader sends a non-standard range unit; a buggy client prefixes the header value incorrectly; a proxy rewrites Range into an unsupported form.
Related errors
- Bad timeRange range. See <a href="https://docs.rsshub.app/ro
- Bad parameter. See <a href="https://docs.rsshub.app/routes/g
- Invalid city
- Invalid channel name
- This category does not exist. Please refer to the documentat
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/9ce242b33e544947.
Report an issue: GitHub.