{"record":{"id":"27c7cb50dc0db8b7","repo":"louislam/uptime-kuma","slug":"invalid-monitor-id","errorCode":null,"errorMessage":"Invalid monitor ID","messagePattern":"Invalid monitor ID","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"server/routers/api-router.js","lineNumber":168,"sourceCode":"\n    const {\n        label,\n        upLabel = \"Up\",\n        downLabel = \"Down\",\n        pendingLabel = \"Pending\",\n        maintenanceLabel = \"Maintenance\",\n        upColor = badgeConstants.defaultUpColor,\n        downColor = badgeConstants.defaultDownColor,\n        pendingColor = badgeConstants.defaultPendingColor,\n        maintenanceColor = badgeConstants.defaultMaintenanceColor,\n        style = badgeConstants.defaultStyle,\n        value, // for demo purpose only\n    } = request.query;\n\n    try {\n        const requestedMonitorId = parseInt(request.params.id, 10);\n        if (Number.isNaN(requestedMonitorId)) {\n            throw new Error(\"Invalid monitor ID\");\n        }\n        const overrideValue = value !== undefined ? parseInt(value) : undefined;\n        const publicMonitor = await isMonitorPublic(requestedMonitorId);\n        const badgeValues = { style };\n\n        if (!publicMonitor) {\n            // return a \"N/A\" badge in naColor (grey), if monitor is not public / not available / non exsitant\n\n            badgeValues.message = \"N/A\";\n            badgeValues.color = badgeConstants.naColor;\n        } else {\n            const heartbeat = await Monitor.getPreviousHeartbeat(requestedMonitorId);\n            const state = overrideValue !== undefined ? overrideValue : heartbeat.status;\n\n            if (label === undefined) {\n                badgeValues.label = \"Status\";\n            } else {\n                badgeValues.label = label;","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/routers/api-router.js#L150-L186","documentation":"Thrown by the status badge route GET /api/badge/:id/status when `parseInt(request.params.id, 10)` returns NaN. The :id path parameter must be a base-10 integer; any non-numeric value (letters, empty, float-formatted) triggers it. The catch block passes the message to sendHttpError().","triggerScenarios":"Requesting the status badge with a non-numeric monitor ID in the URL, e.g. /api/badge/abc/status or /api/badge//status, or passing a monitor slug/name instead of its numeric ID.","commonSituations":"Embedding the badge in a README/HTML with a placeholder or mistyped ID; using a monitor's name instead of its numeric ID; URL-encoding artifacts corrupting the segment.","solutions":["Use the monitor's numeric ID from the dashboard in the badge URL.","Validate the :id segment is an integer before generating the badge link.","Check the rendered URL in the browser devtools for stray characters or empty segments.","If integrating programmatically, build the URL with a verified integer ID."],"exampleFix":"// before\nconst url = `/api/badge/${monitorName}/status`;\n\n// after\nconst url = `/api/badge/${Number(monitor.id)}/status`;","handlingStrategy":"validation","validationCode":"// Build the badge URL only with a verified integer ID\nconst id = Number(monitorId);\nif (!Number.isInteger(id)) throw new Error('monitor id must be an integer');\nconst url = `/api/badge/${id}/status`;","typeGuard":"function isValidMonitorId(id) {\n  return Number.isInteger(Number(id)) && Number(id) > 0;\n}","tryCatchPattern":null,"preventionTips":["Use the numeric monitor ID from the dashboard, never the name/slug.","Generate badge URLs from a trusted source (UI/API).","Validate the ID is an integer in your template before rendering.","Open the badge URL in a browser to confirm it renders before embedding."],"tags":["badge","validation","route-param","monitor-id","public-api"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}