{"record":{"id":"5abc66a1fb059239","repo":"louislam/uptime-kuma","slug":"pm2-process-processname-is-entry-status","errorCode":null,"errorMessage":"PM2 process '${processName}' is ${entry.status}.","messagePattern":"PM2 process '(.+?)' is (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/monitor-types/pm2.js","lineNumber":30,"sourceCode":"     * @param {object} heartbeat The heartbeat object to update.\n     * @returns {Promise<void>}\n     */\n    async check(monitor, heartbeat) {\n        const processName = (monitor.system_service_name || \"\").trim();\n        const processList = await getPM2ProcessList();\n        const entry = processList.find((item) => item.name === processName || item.id === processName);\n\n        if (!entry) {\n            throw new Error(`PM2 process '${processName}' was not found.`);\n        }\n\n        if (entry.status === \"online\") {\n            heartbeat.status = UP;\n            heartbeat.msg = `PM2 process '${processName}' is online.`;\n            return;\n        }\n\n        throw new Error(`PM2 process '${processName}' is ${entry.status}.`);\n    }\n}\n\nmodule.exports = {\n    PM2MonitorType,\n};\n","sourceCodeStart":12,"sourceCodeEnd":37,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/monitor-types/pm2.js#L12-L37","documentation":"The lookup succeeded (an entry was found by name or id) but entry.status !== 'online'. PM2 exposes statuses such as stopped, errored, stopped, launching, etc. The monitor only treats 'online' as healthy, so any other status is surfaced verbatim in the interpolated message and re-thrown to mark the heartbeat DOWN.","triggerScenarios":"PM2 reports the process in any non-online state: stopped (`pm2 stop`), errored (crashed and exhausted restarts), launching, or one of PM2's transient states. The entry exists in the list, so the !entry check passes and execution falls through to the throw at pm2.js:30.","commonSituations":"Process crashed and PM2 left it in 'errored', a manual `pm2 stop`, PM2 still launching after a host restart, or --no-autorestart leaving it stopped after a crash.","solutions":["Inspect with `pm2 describe <name>` to see why it is not online.","Restart with `pm2 restart <name>` and, for persistence, `pm2 save` plus `pm2 startup`.","If status is 'errored', read `pm2 logs <name> --err` for the crash cause and fix the application.","If 'launching' lingers, raise PM2's wait_ready/expire settings or check the app's startup."],"exampleFix":"# before\npm2 stop my-app\n# after\npm2 restart my-app && pm2 save","handlingStrategy":"try-catch","validationCode":"async function assertPm2Online(name) {\n  const list = await getPM2ProcessList();\n  const entry = list.find(p => p.name === name || p.id === name);\n  if (!entry) throw new Error(`PM2 process '${name}' was not found.`);\n  if (entry.status !== 'online') {\n    throw new Error(`PM2 process '${name}' is ${entry.status}.`);\n  }\n}","typeGuard":"function isPm2Online(entry) {\n  return !!entry && entry.status === 'online';\n}","tryCatchPattern":"try {\n  await pm2Monitor.check(monitor, heartbeat);\n} catch (e) {\n  if (/is \\w+\\.$/.test(e.message)) {  // 'is stopped.', 'is errored.'\n    heartbeat.status = DOWN;\n    heartbeat.msg = e.message;     // keep the PM2 status for the UI\n  }\n}","preventionTips":["Enable PM2 keepalive and `pm2 startup` + `pm2 save` so processes return to online after reboot.","Set max_restarts and --no-autorestart policy deliberately; monitor the resulting state.","Alert on 'errored' distinctly from 'stopped' to prioritise crash investigation."],"tags":["pm2","process-monitoring","runtime-state"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}