{"record":{"id":"bc2d47b6ce460cfa","repo":"DIYgod/RSSHub","slug":"unexpected-status-please-open-an-issue","errorCode":null,"errorMessage":"Unexpected status, please open an issue.","messagePattern":"Unexpected status, please open an issue\\.","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":null,"severity":"error","filePath":"lib/routes/uptimerobot/rss.tsx","lineNumber":130,"sourceCode":"        }\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 {\n            throw new InvalidParameterError('Unexpected status, please open an issue.');\n        }\n\n        const desc = renderToString(\n            <>\n                Already {status} for {formatTime(duration)}\n                <br />\n                <br />\n                {showID && id ? (\n                    <>\n                        Monitor ID:{' '}\n                        {link ? (\n                            <a href={link} target=\"_blank\">\n                                {id}\n                            </a>\n                        ) : (\n                            id\n                        )}\n                        <br />","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/uptimerobot/rss.tsx#L112-L148","documentation":"An `InvalidParameterError` at lib/routes/uptimerobot/rss.tsx:130 when the status capture group from the title regex is neither 'UP' nor 'DOWN'. The if/else-if/else chain only handles those two strings; any other value (e.g. 'PAUSED', 'SEEMS_DOWN', 'PENDING') falls through to the throw. This indicates UptimeRobot introduced a new monitor state in their RSS feed.","triggerScenarios":"UptimeRobot adds 'PAUSED' or 'SEEMS_DOWN' as a status that appears in the RSS title; a monitor is in a transitional state that emits a status string the route doesn't enumerate.","commonSituations":"UptimeRobot product update adds new statuses; monitor manually paused producing 'PAUSED' in the feed.","solutions":["Inspect the live RSS feed to find the new status string in the title.","Add the new status to the if/else chain (e.g. `else if (status === 'PAUSED') { monitor.up(duration); }`) or add a no-op branch.","Alternatively, treat any non-'DOWN' status as up."],"exampleFix":"// before\nif (status === 'UP') {\n    monitor.up(duration);\n} else if (status === 'DOWN') {\n    monitor.down(duration);\n} else {\n    throw new InvalidParameterError('Unexpected status, please open an issue.');\n}\n\n// after\nif (status === 'UP') {\n    monitor.up(duration);\n} else if (status === 'DOWN') {\n    monitor.down(duration);\n} else if (status === 'PAUSED' || status === 'SEEMS_DOWN') {\n    // known non-fatal states: do not affect uptime/downtime counters\n} else {\n    throw new InvalidParameterError('Unexpected status, please open an issue.');\n}","handlingStrategy":"fallback","validationCode":"const KNOWN_STATUSES = ['UP', 'DOWN', 'PAUSED', 'SEEMS_DOWN', 'PENDING'];\nconst isKnownStatus = (status: string): boolean => KNOWN_STATUSES.includes(status);","typeGuard":"const isHandledStatus = (s: string): s is 'UP' | 'DOWN' => s === 'UP' || s === 'DOWN';","tryCatchPattern":"try {\n    const items = parseUptimeRobotRss(rss);\n} catch (e) {\n    if (e instanceof InvalidParameterError && e.message.includes('Unexpected status')) {\n        // new UptimeRobot status value — add it to the if/else chain\n        console.error('UptimeRobot RSS contains an unhandled status value');\n    }\n    throw e;\n}","preventionTips":["Fetch the raw RSS feed and enumerate all distinct status strings to discover new ones.","Treat non-'DOWN' statuses as non-downtime rather than throwing — this prevents one new status from breaking the entire feed.","Subscribe to UptimeRobot release notes for new monitor state additions."],"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"}