louislam/uptime-kuma · warning · Error
Invalid monitor ID
Error message
Invalid monitor ID
What it means
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().
Source
Thrown at server/routers/api-router.js:168
const {
label,
upLabel = "Up",
downLabel = "Down",
pendingLabel = "Pending",
maintenanceLabel = "Maintenance",
upColor = badgeConstants.defaultUpColor,
downColor = badgeConstants.defaultDownColor,
pendingColor = badgeConstants.defaultPendingColor,
maintenanceColor = badgeConstants.defaultMaintenanceColor,
style = badgeConstants.defaultStyle,
value, // for demo purpose only
} = request.query;
try {
const requestedMonitorId = parseInt(request.params.id, 10);
if (Number.isNaN(requestedMonitorId)) {
throw new Error("Invalid monitor ID");
}
const overrideValue = value !== undefined ? parseInt(value) : undefined;
const publicMonitor = await isMonitorPublic(requestedMonitorId);
const badgeValues = { style };
if (!publicMonitor) {
// return a "N/A" badge in naColor (grey), if monitor is not public / not available / non exsitant
badgeValues.message = "N/A";
badgeValues.color = badgeConstants.naColor;
} else {
const heartbeat = await Monitor.getPreviousHeartbeat(requestedMonitorId);
const state = overrideValue !== undefined ? overrideValue : heartbeat.status;
if (label === undefined) {
badgeValues.label = "Status";
} else {
badgeValues.label = label;View on GitHub (pinned to 6b5ea01557)
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.
Example fix
// before
const url = `/api/badge/${monitorName}/status`;
// after
const url = `/api/badge/${Number(monitor.id)}/status`; Defensive patterns
Strategy: validation
Validate before calling
// Build the badge URL only with a verified integer ID
const id = Number(monitorId);
if (!Number.isInteger(id)) throw new Error('monitor id must be an integer');
const url = `/api/badge/${id}/status`; Type guard
function isValidMonitorId(id) {
return Number.isInteger(Number(id)) && Number(id) > 0;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The maximum number of hours is 720
- The maximum number of days is 365
- Invalid duration: ${duration}
- Invalid Docker response, is it Docker really a daemon?
- domain_expiry_unsupported_monitor_type
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/27c7cb50dc0db8b7.
Report an issue: GitHub.