DIYgod/RSSHub · error · InvalidParameterError
Unexpected title, please open an issue.
Error message
Unexpected title, please open an issue.
What it means
An `InvalidParameterError` at lib/routes/uptimerobot/rss.tsx:106 when an RSS item's title fails to match `titleRegex = /(.*\S)\s+is\s+([A-Z]+)\s+\((.+)\)/`. The regex expects titles shaped like 'My Server is UP (example.com)'. If UptimeRobot changes their RSS title wording, spacing, or format, every item fails. The message 'open an issue' signals this is a format-drift detector, not a user input error.
Source
Thrown at lib/routes/uptimerobot/rss.tsx:106
async function handler(ctx) {
const id = ctx.req.param('id');
const routeParams = Object.fromEntries(new URLSearchParams(ctx.req.param('routeParams')));
const showID = fallback(undefined, queryToBoolean(routeParams.showID), true);
const rssUrl = `${rootURL}/${id}`;
const rss = await new Parser({
customFields: {
item: ['details:duration'],
},
}).parseURL(rssUrl);
const monitors = {};
const items = rss.items.toReversed().map((item) => {
const titleMatch = item.title!.match(titleRegex);
if (!titleMatch) {
throw new InvalidParameterError('Unexpected title, please open an issue.');
}
const [monitorName, status, id] = titleMatch.slice(1);
if (id !== item.link) {
throw new InvalidParameterError('Monitor ID mismatch, please open an issue.');
}
// id could be a URL, a domain, an IP address, or a hex string. fix it
let link;
try {
link = !id.startsWith('http') && id.includes('.') ? new URL(`http://${id}`).href : new URL(id).href;
} catch {
// ignore
}
const duration = item['details:duration'];
const monitor = (monitors[monitorName] ||= new Monitor(monitorName));
View on GitHub (pinned to bed535e087)
Solutions
- Fetch `https://rss.uptimerobot.com/{id}` directly in a browser and inspect the actual `<title>` tags to see the new format.
- Update `titleRegex` at line 9 to match the current title wording.
- Verify the `:id` path parameter is a valid UptimeRobot RSS feed identifier.
Example fix
// before const titleRegex = /(.*\S)\s+is\s+([A-Z]+)\s+\((.+)\)/; // after (example if UptimeRobot adds 'Status:' prefix) const titleRegex = /(?:Status:\s*)?(.*\S)\s+is\s+([A-Z]+)\s+\((.+)\)/;
Defensive patterns
Strategy: type-guard
Type guard
const titleRegex = /(.*\S)\s+is\s+([A-Z]+)\s+\((.+)\)/; const isExpectedTitle = (title: string): boolean => titleRegex.test(title);
Try / catch
try {
const items = parseUptimeRobotRss(rss);
} catch (e) {
if (e instanceof InvalidParameterError && e.message.includes('Unexpected title')) {
// UptimeRobot RSS format changed — fetch raw feed and update titleRegex
console.error('UptimeRobot RSS title format drift detected; update titleRegex');
}
throw e;
} Prevention
- Periodically fetch the raw UptimeRobot RSS feed to detect title format changes early.
- Subscribe to UptimeRobot changelog/announcements for RSS format updates.
- Make the title regex tolerant of minor wording changes (optional prefixes, flexible whitespace).
When it happens
Trigger: UptimeRobot updates their RSS title template (e.g. adds emoji, changes 'is' to 'has been', reorders fields); a monitor name itself contains ' is ' causing a greedy regex mismatch; the RSS feed ID (`:id` path param) is wrong and points to a different feed format.
Common situations: UptimeRobot ships a UI/RSS update; the monitor name has unusual characters; old `:id` from a deleted monitor now returns a generic feed.
Related errors
- Monitor ID mismatch, please open an issue.
- Unexpected status, please open an issue.
- Unable to locate stores data for region ${region}
- Unknown section type: ${section.type}
- 无法解析页面数据,请检查漫画 ID 是否正确或页面结构是否变动
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/58a702021e7eadf4.
Report an issue: GitHub.