{"record":{"id":"40b31bd5577b54f6","repo":"louislam/uptime-kuma","slug":"pagertree-notification-failed-with-invalid-respons","errorCode":null,"errorMessage":"PagerTree notification failed with invalid response!","messagePattern":"PagerTree notification failed with invalid response!","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"server/notification-providers/pagertree.js","lineNumber":47,"sourceCode":"\n            if (heartbeatJSON.status === DOWN) {\n                const title = `Uptime Kuma Monitor \"${monitorJSON.name}\" is DOWN`;\n                return this.postNotification(notification, title, monitorJSON, heartbeatJSON);\n            }\n        } catch (error) {\n            this.throwGeneralAxiosError(error);\n        }\n    }\n\n    /**\n     * Check if result is successful, result code should be in range 2xx\n     * @param {object} result Axios response object\n     * @returns {void}\n     * @throws {Error} The status code is not in range 2xx\n     */\n    checkResult(result) {\n        if (result.status == null) {\n            throw new Error(\"PagerTree notification failed with invalid response!\");\n        }\n        if (result.status < 200 || result.status >= 300) {\n            throw new Error(\"PagerTree notification failed with status code \" + result.status);\n        }\n    }\n\n    /**\n     * Send the message\n     * @param {BeanModel} notification Message title\n     * @param {string} title Message title\n     * @param {object} monitorJSON Monitor details (For Up/Down only)\n     * @param {object} heartbeatJSON Heartbeat details (For Up/Down only)\n     * @param {?string} eventAction Action event for PagerTree (create, resolve)\n     * @returns {Promise<string>} Success state\n     */\n    async postNotification(notification, title, monitorJSON, heartbeatJSON, eventAction = \"create\") {\n        if (eventAction == null) {\n            return \"No action required\";","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/notification-providers/pagertree.js#L29-L65","documentation":"PagerTree's checkResult(result) guard fires when result.status == null — the response object exists but has no numeric status. Mirror of the PagerDuty pattern: a defensive check for an unexpected/empty response before the 2xx range test.","triggerScenarios":"A custom axios adapter/interceptor or an intermediary proxy returned a response object without a status field; mocked responses in tests omit status; the PagerTree response was malformed in transit.","commonSituations":"Misbehaving reverse proxy; axios response transformer that drops status; tests with incomplete mocks.","solutions":["Log the raw result object to identify why status is null.","Fix/remove custom axios interceptors or adapters on this request path.","Ensure any proxy in front of PagerTree preserves the HTTP status line.","Set status explicitly in any mocked responses."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"/** @param {unknown} r */\nfunction hasHttpStatus(r) {\n    return typeof r === \"object\" && r !== null &&\n        typeof r.status === \"number\" && r.status >= 100 && r.status < 600;\n}","tryCatchPattern":"if (!hasHttpStatus(result)) {\n    throw new Error(\"PagerTree returned a malformed response (no HTTP status)\");\n}","preventionTips":["Always set status on mocked responses.","Do not run axios interceptors that strip the status field.","Ensure proxies preserve the status line."],"tags":["pagertree","http","validation","response-shape","defensive"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}