louislam/uptime-kuma · error · Error

Invalid PM2 process name.

Error message

Invalid PM2 process name.

What it means

Thrown by Monitor.validate() for type "pm2" when system_service_name contains a C0 control character (\u0000-\u001F) or DEL (\u007F). PM2 process names are passed to the pm2 process manager and CLI, where control characters corrupt output or argument parsing. Unlike system-service, PM2 allows spaces and most printable characters, so only invisible control bytes are rejected.

Source

Thrown at server/model/monitor.js:1706

            } catch (e) {
                throw new Error(`Accepted status codes must be valid JSON: ${e.message}`);
            }
        }

        if (["system-service", "pm2"].includes(this.type)) {
            this.system_service_name = (this.system_service_name || "").trim();

            if (!this.system_service_name) {
                throw new Error(this.type === "pm2" ? "PM2 process name is required." : "Service Name is required.");
            }
        }

        if (this.type === "system-service" && !/^[a-zA-Z0-9._\-@]+$/.test(this.system_service_name)) {
            throw new Error("Invalid service name. Please use the internal Service Name (no spaces).");
        }

        if (this.type === "pm2" && /[\u0000-\u001F\u007F]/.test(this.system_service_name)) {
            throw new Error("Invalid PM2 process name.");
        }

        if (this.type === "ping") {
            // ping parameters validation
            if (this.packetSize && (this.packetSize < PING_PACKET_SIZE_MIN || this.packetSize > PING_PACKET_SIZE_MAX)) {
                throw new Error(
                    `Packet size must be between ${PING_PACKET_SIZE_MIN} and ${PING_PACKET_SIZE_MAX} (default: ${PING_PACKET_SIZE_DEFAULT})`
                );
            }

            if (
                this.ping_per_request_timeout &&
                (this.ping_per_request_timeout < PING_PER_REQUEST_TIMEOUT_MIN ||
                    this.ping_per_request_timeout > PING_PER_REQUEST_TIMEOUT_MAX)
            ) {
                throw new Error(
                    `Per-ping timeout must be between ${PING_PER_REQUEST_TIMEOUT_MIN} and ${PING_PER_REQUEST_TIMEOUT_MAX} seconds (default: ${PING_PER_REQUEST_TIMEOUT_DEFAULT})`
                );

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Sanitize the name by removing \u0000-\u001F and \u007F, e.g. name.replace(/[\u0000-\u001F\u007F]/g, "").
  2. Re-type the PM2 process name by hand rather than copy-pasting from terminal output.
  3. Run `pm2 jlist` and copy the `name` field verbatim to ensure a clean value.

Example fix

// before
const name = rawPm2Line; // contains trailing \r
// after
const name = rawPm2Line.replace(/[\u0000-\u001F\u007F]/g, "").trim();
Defensive patterns

Strategy: validation

Validate before calling

function cleanPm2Name(name) {
  return String(name || "").replace(/[\u0000-\u001F\u007F]/g, "").trim();
}
monitor.system_service_name = cleanPm2Name(monitor.system_service_name);

Type guard

function isCleanPm2Name(name) {
  return typeof name === "string" && name.length > 0 && !/[\u0000-\u001F\u007F]/.test(name);
}

Try / catch

try {
  await bean.validate();
} catch (e) {
  if (/Invalid PM2 process name/.test(e.message)) {
    monitor.system_service_name = monitor.system_service_name.replace(/[\u0000-\u001F\u007F]/g, "");
    return retry();
  }
  throw e;
}

Prevention

When it happens

Trigger: Save a pm2 monitor whose process name was copied from a terminal/log line containing a stray \r, \n, \t, NUL, or DEL byte. Programmatically constructed names that embed escape sequences or unsplit newline-delimited lists.

Common situations: Pasting the process name from `pm2 list` output where a terminal wrapped a carriage return into the selection; importing monitors from a CSV that was edited in a spreadsheet adding non-breaking/control chars; build pipelines injecting \n into names.

Related errors


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