{"record":{"id":"2ff32de63e6ee36c","repo":"DIYgod/RSSHub","slug":"monitor-id-mismatch-please-open-an-issue","errorCode":null,"errorMessage":"Monitor ID mismatch, please open an issue.","messagePattern":"Monitor ID mismatch, please open an issue\\.","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":null,"severity":"error","filePath":"lib/routes/uptimerobot/rss.tsx","lineNumber":111,"sourceCode":"\n    const rssUrl = `${rootURL}/${id}`;\n    const rss = await new Parser({\n        customFields: {\n            item: ['details:duration'],\n        },\n    }).parseURL(rssUrl);\n\n    const monitors = {};\n\n    const items = rss.items.toReversed().map((item) => {\n        const titleMatch = item.title!.match(titleRegex);\n        if (!titleMatch) {\n            throw new InvalidParameterError('Unexpected title, please open an issue.');\n        }\n        const [monitorName, status, id] = titleMatch.slice(1);\n\n        if (id !== item.link) {\n            throw new InvalidParameterError('Monitor ID mismatch, please open an issue.');\n        }\n\n        // id could be a URL, a domain, an IP address, or a hex string. fix it\n        let link;\n        try {\n            link = !id.startsWith('http') && id.includes('.') ? new URL(`http://${id}`).href : new URL(id).href;\n        } catch {\n            // ignore\n        }\n\n        const duration = item['details:duration'];\n        const monitor = (monitors[monitorName] ||= new Monitor(monitorName));\n\n        if (status === 'UP') {\n            monitor.up(duration);\n        } else if (status === 'DOWN') {\n            monitor.down(duration);\n        } else {","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/uptimerobot/rss.tsx#L93-L129","documentation":"An `InvalidParameterError` at lib/routes/uptimerobot/rss.tsx:111 fired when the monitor ID extracted from the RSS title's capture group 3 does not equal `item.link`. The route assumes UptimeRobot puts the same identifier in both the title parenthetical and the `<link>` element. A format change that decouples them triggers this on every item.","triggerScenarios":"UptimeRobot changes the title to show a display name in parentheses while `<link>` holds the raw monitor ID; the `:id` feed is from a new UptimeRobot product tier with a different link scheme; URL-encoding differences between title and link.","commonSituations":"UptimeRobot RSS format update; monitor configured with a friendly alias that appears in the title but not the link.","solutions":["Inspect a live RSS feed to compare the title parenthetical value with `<link>` for each item.","If the mismatch is intentional, relax or remove the strict equality check at line 110–112 and derive `link` from whichever field is more reliable.","Report the format change to the route maintainer (Rongronggg9) with a sample feed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":"const titleIdMatchesLink = (titleId: string, link: string): boolean =>\n    titleId === link;","tryCatchPattern":"try {\n    const items = parseUptimeRobotRss(rss);\n} catch (e) {\n    if (e instanceof InvalidParameterError && e.message.includes('Monitor ID mismatch')) {\n        // title ID and link diverged — inspect raw feed to understand the new format\n        console.error('UptimeRobot RSS title/link ID mismatch; format changed');\n    }\n    throw e;\n}","preventionTips":["If UptimeRobot decouples title display names from link IDs, relax the strict equality to a startsWith or contains check.","Monitor the raw RSS feed for structural changes alongside error 788.","Report the format change to the route maintainer with a sample item."],"tags":["parsing","format-change","rss","validation","uptimerobot"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}