{"record":{"id":"272e2887755fdcef","repo":"louislam/uptime-kuma","slug":"accepted-status-codes-are-not-all-strings","errorCode":null,"errorMessage":"Accepted status codes are not all strings","messagePattern":"Accepted status codes are not all strings","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/server.js","lineNumber":753,"sourceCode":"            }\n        });\n\n        // ***************************\n        // Auth Only API\n        // ***************************\n\n        // Add a new monitor\n        socket.on(\"add\", async (monitor, callback) => {\n            try {\n                checkLogin(socket);\n                let bean = R.dispense(\"monitor\");\n\n                let notificationIDList = monitor.notificationIDList;\n                delete monitor.notificationIDList;\n\n                // Ensure status code ranges are strings\n                if (!monitor.accepted_statuscodes.every((code) => typeof code === \"string\")) {\n                    throw new Error(\"Accepted status codes are not all strings\");\n                }\n                monitor.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes);\n                delete monitor.accepted_statuscodes;\n\n                monitor.kafkaProducerBrokers = JSON.stringify(monitor.kafkaProducerBrokers);\n                monitor.kafkaProducerSaslOptions = JSON.stringify(monitor.kafkaProducerSaslOptions);\n\n                monitor.conditions = JSON.stringify(monitor.conditions);\n\n                monitor.rabbitmqNodes = JSON.stringify(monitor.rabbitmqNodes);\n\n                /*\n                 * List of frontend-only properties that should not be saved to the database.\n                 * Should clean up before saving to the database.\n                 */\n                const frontendOnlyProperties = [\n                    \"humanReadableInterval\",\n                    \"globalpingdnsresolvetypeoptions\",","sourceCodeStart":735,"sourceCodeEnd":771,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/server.js#L735-L771","documentation":"Thrown by the 'add' (addMonitor) socket handler when not every element of monitor.accepted_statuscodes is a string (typeof code === 'string'). The array is JSON-stringified into accepted_statuscodes_json, so the contract requires string ranges like ['200-299','300']. The callback returns {ok:false, msg}.","triggerScenarios":"A client emits 'add' with accepted_statuscodes containing numbers (e.g. [200,301]) or mixed types, instead of string ranges. Commonly a regression in the frontend serialization or a third-party API client.","commonSituations":"Frontend refactor that sends numbers instead of strings; a custom script creating monitors via socket.io that builds the array from numeric literals; migration tool not coercing types.","solutions":["Send accepted_statuscodes as an array of string ranges, e.g. ['200-299','401'].","Coerce each entry to String(code) before emitting the 'add' event.","Validate the array shape on the client before submit.","If writing a migration, map numeric codes to their string form."],"exampleFix":"// before\nsocket.emit('add', { ...monitor, accepted_statuscodes: [200, 301] }, cb);\n\n// after\nconst codes = monitor.accepted_statuscodes.map((c) => String(c));\nsocket.emit('add', { ...monitor, accepted_statuscodes: codes }, cb);","handlingStrategy":"type-guard","validationCode":"// Coerce status codes to strings before emitting add\nconst codes = Array.isArray(monitor.accepted_statuscodes)\n  ? monitor.accepted_statuscodes.map((c) => String(c))\n  : ['200-299'];\nsocket.emit('add', { ...monitor, accepted_statuscodes: codes }, cb);","typeGuard":"function isStringCodeArray(arr) {\n  return Array.isArray(arr) && arr.every((c) => typeof c === 'string' && c.length > 0);\n}","tryCatchPattern":null,"preventionTips":["Always send accepted_statuscodes as string ranges like ['200-299'].","Map numeric codes to String() at the boundary.","Validate the array shape on the client before submit.","In migrations, normalize types in an adapter layer."],"tags":["monitor","validation","type-coercion","status-codes","socket"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}