DIYgod/RSSHub · error · TypeError
Invalid segment
Error message
Invalid segment: ${part} What it means
parseDuration splits a time string on ':' after stripping every character that is not a digit or colon, then Number()-converts each segment. If any segment cannot be parsed as a number the function throws a TypeError naming the offending segment. In practice the sanitisation regex makes non-numeric segments very hard to produce, so this is a defensive guard against unexpected input shapes.
Solutions
- Normalise the input before calling parseDuration: convert full-width digits to ASCII and unicode colons to ':' (e.g. value.normalize('NFKC')).
- Wrap the call in try/catch and treat the duration as unknown on failure rather than crashing the route.
- Validate with a regex like /^(\d{1,2}:){0,2}\d{1,2}$/ before calling parseDuration.
Example fix
// before
const seconds = parseDuration(raw);
// after
const seconds = /^[0-9]+(:[0-9]+){0,2}$/.test(raw.trim()) ? parseDuration(raw) : undefined; Defensive patterns
Strategy: validation
Validate before calling
function isValidDuration(s: string | null | undefined): boolean {
return typeof s === 'string' && /^\d{1,2}(:\d{1,2}){0,2}$/.test(s.trim());
}
// before calling parseDuration
if (!isValidDuration(raw)) return undefined; Type guard
const isParsableDuration = (s: unknown): s is string =>
typeof s === 'string' && /^\d{1,2}(:\d{1,2}){0,2}$/.test(s.trim()); Try / catch
try {
return parseDuration(raw);
} catch (e) {
if (e instanceof TypeError && /Invalid segment/.test(e.message)) return undefined;
throw e;
} Prevention
- Normalise input with .normalize('NFKC') to fold full-width digits/colons before parsing.
- Validate with a strict regex before calling parseDuration so malformed input never reaches the loop.
- Treat duration parsing as best-effort in route code - wrap it and degrade gracefully.
When it happens
Trigger: Calling parseDuration with a string that, after replaceAll(/[^\d:]/g,''), still yields a segment Number() rejects as NaN (e.g. unusual unicode digit separators that survive the regex, or a programmatically-constructed input bypassing the documented formats 'SS', 'MM:SS', 'HH:MM:SS').
Common situations: A feed passing a localized duration format (e.g. full-width digits, non-ASCII colon variants) that the strip regex keeps; unit tests feeding adversarial strings; an upstream format change in a media route that hands parseDuration a malformed value.
Related errors
- cannot inflate a stripped jpeg
- 成功获取数据对象,但未找到作品基本信息
- 无法正确获取快递公司列表:请稍后重试
- 文章列表不存在或为空
- Expected ' ' property not found in pageProps for category
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/009bb16f5582bed4.
Report an issue: GitHub.
Appendix: source
Thrown at lib/utils/helpers.ts:60
return searchParamsString ?? new URLSearchParams(searchParams).toString();
}
/**
* parse duration string to seconds
* @param {string} timeStr - duration string like "01:01:01" / "01:01" / "59"
* @returns {number} - total seconds
*/
export function parseDuration(timeStr: string | undefined | null): number | undefined {
if (!timeStr) {
return;
}
const clean = timeStr.trim().replaceAll(/[^\d:]/g, '');
const parts = clean.split(':');
let total = 0;
for (const [idx, part] of parts.entries()) {
const n = Number(part);
if (Number.isNaN(n)) {
throw new TypeError(`Invalid segment: ${part}`);
}
total += n * Math.pow(60, parts.length - 1 - idx);
}
return total;
}
View on GitHub (pinned to bed535e087)