{"record":{"id":"af8048924bb0647a","repo":"louislam/uptime-kuma","slug":"res-status","errorCode":null,"errorMessage":"${res.status()}","messagePattern":"\\$\\{res\\.status\\(\\)\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/monitor-types/real-browser-monitor-type.js","lineNumber":292,"sourceCode":"            await page.waitForTimeout(monitor.screenshot_delay);\n        }\n\n        let filename = jwt.sign(monitor.id, server.jwtSecret) + \".png\";\n\n        await page.screenshot({\n            path: path.join(Database.screenshotDir, filename),\n        });\n\n        await context.close();\n\n        if (res.status() >= 200 && res.status() < 400) {\n            heartbeat.status = UP;\n            heartbeat.msg = res.status();\n\n            const timing = res.request().timing();\n            heartbeat.ping = timing.responseEnd;\n        } else {\n            throw new Error(res.status() + \"\");\n        }\n    }\n}\n\nmodule.exports = {\n    RealBrowserMonitorType,\n    testChrome,\n    resetChrome,\n    testRemoteBrowser,\n};\n","sourceCodeStart":274,"sourceCodeEnd":303,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/monitor-types/real-browser-monitor-type.js#L274-L303","documentation":"After navigation and screenshot capture, the monitor reads res.status() (Playwright HTTP status of the main response). Statuses in [200,400) are UP; anything else (>=400 or an error status) is thrown as res.status() + '' so the heartbeat is marked DOWN with the code. This converts a non-success HTTP response into a monitor failure.","triggerScenarios":"The page responded with an HTTP error: 404, 500, 502, 503, etc. The response object exists (navigation completed) but the status code is >= 400, so the else branch at real-browser-monitor-type.js:292 throws.","commonSituations":"Target page returning 404/500, upstream gateway 502/504, redirect to an error page, or maintenance pages served with a non-2xx code.","solutions":["Open the URL in a browser and confirm the HTTP status (DevTools Network or curl -i).","Fix the upstream service returning the error code.","If the error page is intentional, point the monitor at the real resource URL.","For 502/504 from a reverse proxy, check the backend service health."],"exampleFix":"# before\nGET / -> 502 Bad Gateway\n# after\n# restart the backend behind the reverse proxy, then re-test","handlingStrategy":"validation","validationCode":"const http = require('http');\nfunction preflightHttp(url) {\n  return new Promise((resolve, reject) => {\n    http.get(url, res => {\n      if (res.statusCode >= 400) reject(new Error(`Preflight: HTTP ${res.statusCode}`));\n      else resolve(res.statusCode);\n    }).on('error', reject);\n  });\n}","typeGuard":"function isHttpErrorStatus(code) { return typeof code === 'number' && code >= 400; }","tryCatchPattern":"try {\n  await realBrowserMonitor.check(monitor, heartbeat, server);\n} catch (e) {\n  if (/^\\d{3}$/.test(e.message)) {\n    heartbeat.status = DOWN;\n    heartbeat.msg = `HTTP ${e.message}`;\n  }\n}","preventionTips":["Point the real-browser monitor at a known-good URL.","Use a plain HTTP monitor alongside to separate HTTP errors from page errors.","Alert with the HTTP code so responders can route 5xx vs 4xx."],"tags":["chromium","http","monitor","runtime-state"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}