louislam/uptime-kuma · error · Error

Accepted status codes are not all strings

Error message

Accepted status codes are not all strings

What it means

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}.

Source

Thrown at server/server.js:753

            }
        });

        // ***************************
        // Auth Only API
        // ***************************

        // Add a new monitor
        socket.on("add", async (monitor, callback) => {
            try {
                checkLogin(socket);
                let bean = R.dispense("monitor");

                let notificationIDList = monitor.notificationIDList;
                delete monitor.notificationIDList;

                // Ensure status code ranges are strings
                if (!monitor.accepted_statuscodes.every((code) => typeof code === "string")) {
                    throw new Error("Accepted status codes are not all strings");
                }
                monitor.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes);
                delete monitor.accepted_statuscodes;

                monitor.kafkaProducerBrokers = JSON.stringify(monitor.kafkaProducerBrokers);
                monitor.kafkaProducerSaslOptions = JSON.stringify(monitor.kafkaProducerSaslOptions);

                monitor.conditions = JSON.stringify(monitor.conditions);

                monitor.rabbitmqNodes = JSON.stringify(monitor.rabbitmqNodes);

                /*
                 * List of frontend-only properties that should not be saved to the database.
                 * Should clean up before saving to the database.
                 */
                const frontendOnlyProperties = [
                    "humanReadableInterval",
                    "globalpingdnsresolvetypeoptions",

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Send accepted_statuscodes as an array of string ranges, e.g. ['200-299','401'].
  2. Coerce each entry to String(code) before emitting the 'add' event.
  3. Validate the array shape on the client before submit.
  4. If writing a migration, map numeric codes to their string form.

Example fix

// before
socket.emit('add', { ...monitor, accepted_statuscodes: [200, 301] }, cb);

// after
const codes = monitor.accepted_statuscodes.map((c) => String(c));
socket.emit('add', { ...monitor, accepted_statuscodes: codes }, cb);
Defensive patterns

Strategy: type-guard

Validate before calling

// Coerce status codes to strings before emitting add
const codes = Array.isArray(monitor.accepted_statuscodes)
  ? monitor.accepted_statuscodes.map((c) => String(c))
  : ['200-299'];
socket.emit('add', { ...monitor, accepted_statuscodes: codes }, cb);

Type guard

function isStringCodeArray(arr) {
  return Array.isArray(arr) && arr.every((c) => typeof c === 'string' && c.length > 0);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/272e2887755fdcef. Report an issue: GitHub.