{"record":{"id":"f117b625159b1c8d","repo":"louislam/uptime-kuma","slug":"invalid-rabbitmq-nodes","errorCode":null,"errorMessage":"Invalid RabbitMQ Nodes","messagePattern":"Invalid RabbitMQ Nodes","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/monitor-types/rabbitmq.js","lineNumber":17,"sourceCode":"const { MonitorType } = require(\"./monitor-type\");\nconst { log, UP } = require(\"../../src/util\");\nconst { axiosAbortSignal } = require(\"../util-server\");\nconst axios = require(\"axios\");\n\nclass RabbitMqMonitorType extends MonitorType {\n    name = \"rabbitmq\";\n\n    /**\n     * @inheritdoc\n     */\n    async check(monitor, heartbeat, server) {\n        let baseUrls = [];\n        try {\n            baseUrls = JSON.parse(monitor.rabbitmqNodes);\n        } catch (error) {\n            throw new Error(\"Invalid RabbitMQ Nodes\");\n        }\n\n        if (baseUrls.length === 0) {\n            throw new Error(\"No RabbitMQ nodes configured\");\n        }\n\n        const errors = [];\n\n        for (let i = 0; i < baseUrls.length; i++) {\n            const baseUrl = baseUrls[i];\n            const nodeIndex = i + 1;\n\n            try {\n                await this.checkSingleNode(monitor, baseUrl, `${nodeIndex}/${baseUrls.length}`);\n                // If checkSingleNode succeeds (doesn't throw), set heartbeat to UP\n                heartbeat.status = UP;\n                heartbeat.msg =\n                    baseUrls.length === 1","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/monitor-types/rabbitmq.js#L1-L35","documentation":"The RabbitMQ monitor stores its node list as a JSON string in monitor.rabbitmqNodes and parses it at the top of check(). If JSON.parse throws, the raw field is not valid JSON, and the catch rethrows a generic 'Invalid RabbitMQ Nodes' error that hides the original parse detail. This fires before any node is contacted, so it is purely a configuration-shape problem.","triggerScenarios":"monitor.rabbitmqNodes contains a non-JSON string: a comma-separated list like 'http://host:15672', a bare URL, trailing commas, single quotes, or accidental whitespace/newlines that break the parser.","commonSituations":"User types URLs separated by commas instead of a JSON array; UI or migration left a malformed value; someone edited the DB directly; mixing double/single quotes.","solutions":["Store the nodes as a JSON array of strings, e.g. [\"http://rabbit-1:15672\",\"http://rabbit-2:15672\"].","Validate the value with JSON.parse in a console before saving the monitor.","Re-enter the nodes through the monitor editor so the frontend serializes them correctly.","If editing the DB directly, wrap the list in brackets and double-quote each URL."],"exampleFix":"// before\nmonitor.rabbitmqNodes = \"http://rabbit-1:15672, http://rabbit-2:15672\";\n// after\nmonitor.rabbitmqNodes = JSON.stringify([\"http://rabbit-1:15672\",\"http://rabbit-2:15672\"]);","handlingStrategy":"validation","validationCode":"function parseRabbitNodes(raw) {\n  if (typeof raw !== 'string' || raw.trim() === '') {\n    throw new Error('rabbitmqNodes is empty');\n  }\n  let arr;\n  try { arr = JSON.parse(raw); }\n  catch (e) { throw new Error(`rabbitmqNodes is not valid JSON: ${e.message}`); }\n  if (!Array.isArray(arr)) throw new Error('rabbitmqNodes must be a JSON array');\n  return arr;\n}","typeGuard":"function isJsonStringArray(s) {\n  try {\n    const v = JSON.parse(s);\n    return Array.isArray(v) && v.every(x => typeof x === 'string');\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  await rabbitmqMonitor.check(monitor, heartbeat, server);\n} catch (e) {\n  if (/Invalid RabbitMQ Nodes/.test(e.message)) {\n    // prompt user to re-enter nodes via the editor; do not retry blindly\n    log.error('Reconfigure rabbitmqNodes as a JSON array of URLs');\n  }\n  throw e;\n}","preventionTips":["Always JSON.stringify the node array before persisting it.","Validate the field in the frontend on save and reject non-array input.","Never let users type a comma-separated string; use a structured editor."],"tags":["rabbitmq","json","config","validation"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}