{"record":{"id":"b3865a1cad129758","repo":"louislam/uptime-kuma","slug":"the-monitor-implementation-is-incorrect-non-up-er","errorCode":null,"errorMessage":"The monitor implementation is incorrect, non-UP error must throw error inside check()","messagePattern":"The monitor implementation is incorrect, non-UP error must throw error inside check\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/model/monitor.js","lineNumber":875,"sourceCode":"                        this.radiusUsername,\n                        this.radiusPassword,\n                        this.radiusCalledStationId,\n                        this.radiusCallingStationId,\n                        this.radiusSecret,\n                        port,\n                        this.interval * 1000 * 0.4\n                    );\n\n                    bean.msg = resp.code;\n                    bean.status = UP;\n                    bean.ping = dayjs().valueOf() - startTime;\n                } else if (this.type in UptimeKumaServer.monitorTypeList) {\n                    let startTime = dayjs().valueOf();\n                    const monitorType = UptimeKumaServer.monitorTypeList[this.type];\n                    await monitorType.check(this, bean, UptimeKumaServer.getInstance());\n\n                    if (!monitorType.allowCustomStatus && bean.status !== UP) {\n                        throw new Error(\n                            \"The monitor implementation is incorrect, non-UP error must throw error inside check()\"\n                        );\n                    }\n\n                    if (bean.ping === undefined || bean.ping === null) {\n                        bean.ping = dayjs().valueOf() - startTime;\n                    }\n                } else if (this.type === \"kafka-producer\") {\n                    let startTime = dayjs().valueOf();\n\n                    bean.msg = await kafkaProducerAsync(\n                        JSON.parse(this.kafkaProducerBrokers),\n                        this.kafkaProducerTopic,\n                        this.kafkaProducerMessage,\n                        {\n                            allowAutoTopicCreation: this.kafkaProducerAllowAutoTopicCreation,\n                            ssl: this.kafkaProducerSsl,\n                            clientId: `Uptime-Kuma/${version}`,","sourceCodeStart":857,"sourceCodeEnd":893,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/model/monitor.js#L857-L893","documentation":"A contract check for monitor types registered in monitorTypeList (custom/plugin types). After monitorType.check() runs, if bean.status is not UP and the type did not opt into allowCustomStatus, Uptime Kuma treats this as a programmer error: the contract is to either leave status UP or throw an error inside check(), never silently set DOWN/PENDING.","triggerScenarios":"A custom monitor type's check() sets bean.status to DOWN or PENDING without throwing, and the type does not set allowCustomStatus=true.","commonSituations":"Plugin/monitor-type author forgot to throw; monitor type still under development; incompatible plugin version against this Uptime Kuma release.","solutions":["If you author the monitor type, throw an Error inside check() instead of setting bean.status=DOWN","If the type legitimately needs custom statuses, set allowCustomStatus=true on the monitor type definition","If you only consume the plugin, report the bug or upgrade to a fixed version"],"exampleFix":"// before\nmonitorType.check = (monitor, bean, server) => { bean.status = DOWN; };\n\n// after\nmonitorType.check = (monitor, bean, server) => { throw new Error(\"container not running\"); };","handlingStrategy":"validation","validationCode":"// For monitor-type authors: never set a non-UP status silently in check()\nclass MyType extends MonitorType {\n  async check(monitor, bean, server) {\n    const ok = await probe(monitor);\n    if (!ok) throw new Error(\"probe failed\"); // throw, do not set bean.status = DOWN\n    bean.status = UP;\n  }\n}","typeGuard":"// If your type genuinely emits custom statuses, opt in\nmonitorType.allowCustomStatus = true;","tryCatchPattern":null,"preventionTips":["Treat check() as 'either UP or throw' unless allowCustomStatus is set","Add a unit test that asserts check() throws on failure rather than setting DOWN"],"tags":["plugin","developer","monitor-type","contract"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}