{"record":{"id":"c8db32e0d1ca4653","repo":"louislam/uptime-kuma","slug":"child-monitors-down-downchildren-join-p","errorCode":null,"errorMessage":"Child monitors down: ${downChildren.join(\", \")}; pending: ${pendingChildren.join(\", \")}","messagePattern":"Child monitors down: (.+?); pending: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/monitor-types/group.js","lineNumber":73,"sourceCode":"            heartbeat.status = UP;\n            heartbeat.msg = \"All children up and running\";\n            return;\n        }\n\n        if (worstStatus === PENDING) {\n            heartbeat.status = PENDING;\n            heartbeat.msg = `Pending child monitors: ${pendingChildren.join(\", \")}`;\n            return;\n        }\n\n        let message = `Child monitors down: ${downChildren.join(\", \")}`;\n\n        if (pendingChildren.length > 0) {\n            message += `; pending: ${pendingChildren.join(\", \")}`;\n        }\n\n        // Throw to leverage the generic retry handling and notification flow\n        throw new Error(message);\n    }\n}\n\nmodule.exports = {\n    GroupMonitorType,\n};\n","sourceCodeStart":55,"sourceCodeEnd":80,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/monitor-types/group.js#L55-L80","documentation":"Thrown by the group monitor when at least one active child's last heartbeat is DOWN. The throw is intentional: it leverages the generic retry/notification flow to mark the group DOWN and alert. Pending children are appended to the message when present. This is not an exception to suppress — it is how a group reports failure.","triggerScenarios":"In GroupMonitorType.check, the loop finds a child with lastBeat.status === DOWN (and active), so worstStatus becomes DOWN. The code then constructs 'Child monitors down: X' and throws. If some children are also PENDING they are appended after '; pending:'.","commonSituations":"A real downstream outage on one or more child monitors, a child stuck DOWN after a transient blip, or children that are misconfigured and perpetually DOWN.","solutions":["Investigate and resolve the listed DOWN child monitors first","If a child is permanently broken, pause (deactivate) it so the group ignores it","Add children to the group only after they have at least one heartbeat to avoid the pending list","Do not catch-and-swallow this error — it drives the group's DOWN status and notifications"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Inspect child statuses before relying on the group result\nconst children = await Monitor.getChildren(monitor.id);\nif (children.length === 0) {\n    // group will be PENDING, not an error\n    return;\n}","typeGuard":null,"tryCatchPattern":"// The throw is intentional — let it propagate to drive DOWN status.\n// Only catch if you need custom aggregation.\ntry {\n    await groupMonitor.check(monitor, heartbeat, server);\n} catch (e) {\n    if (e.message.startsWith(\"Child monitors down:\")) {\n        // expected DOWN path; re-throw so notifications fire\n        throw e;\n    }\n    throw e;\n}","preventionTips":["Resolve DOWN children promptly so the group recovers","Pause broken children instead of leaving them DOWN","Ensure each child has produced at least one heartbeat before relying on the group"],"tags":["group","aggregate","down","notification"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}