{"record":{"id":"5d6a1aab172b1413","repo":"louislam/uptime-kuma","slug":"yzj-s-server-did-not-respond-with-the-expected-res","errorCode":null,"errorMessage":"yzj's server did not respond with the expected result","messagePattern":"yzj's server did not respond with the expected result","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/notification-providers/yzj.js","lineNumber":33,"sourceCode":"            if (heartbeatJSON !== null) {\n                msg = `${this.statusToString(heartbeatJSON[\"status\"])} ${monitorJSON[\"name\"]} \\n> ${heartbeatJSON[\"msg\"]}\\n> Time (${heartbeatJSON[\"timezone\"]}): ${heartbeatJSON[\"localDateTime\"]}`;\n            }\n\n            let config = {\n                headers: {\n                    \"Content-Type\": \"application/json\",\n                },\n            };\n            const params = {\n                content: msg,\n            };\n            // yzjtype=0 => general robot\n            const url = `${notification.yzjWebHookUrl}?yzjtype=0&yzjtoken=${notification.yzjToken}`;\n            config = this.getAxiosConfigWithProxy(config);\n\n            const result = await axios.post(url, params, config);\n            if (!result.data?.success) {\n                throw new Error(result.data?.errmsg ?? \"yzj's server did not respond with the expected result\");\n            }\n            return okMsg;\n        } catch (error) {\n            this.throwGeneralAxiosError(error);\n        }\n    }\n\n    /**\n     * Convert status constant to string\n     * @param {string} status The status constant\n     * @returns {string} status\n     */\n    statusToString(status) {\n        switch (status) {\n            case DOWN:\n                return \"❌\";\n            case UP:\n                return \"✅\";","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/notification-providers/yzj.js#L15-L51","documentation":"Thrown by the YZJ (ZhenTong / DingTalk-like robot) provider as a fallback when result.data.success is falsy AND result.data.errmsg is also missing. YZJ's robot webhook normally returns {success:boolean, errmsg?:string}; this branch covers responses where neither convention holds, so the provider cannot extract a specific reason.","triggerScenarios":"YZJ server returned 2xx with an unexpected body (schema change, maintenance page parsed as 200, internal error without errmsg), or a proxy returned a synthetic success-less JSON. The actual error message is unrecoverable from the response alone.","commonSituations":"yzjWebHookUrl pointing at an outdated endpoint, yzjToken expired, YZJ robot disabled, or upstream API version change dropping the success/errmsg fields.","solutions":["From the host, POST to {yzjWebHookUrl}?yzjtype=0&yzjtoken={token} with a test content payload and inspect the raw response body.","Verify yzjWebHookUrl is the current robot incoming-webhook URL provided by YZJ.","Regenerate yzjToken if the robot was recreated.","If the body shape changed, update the success/errmsg field access in yzj.js:32-33 to match."],"exampleFix":"// before\nif (!result.data?.success) {\n    throw new Error(result.data?.errmsg ?? \"yzj's server did not respond with the expected result\");\n}\n// after (preserve the raw body so the operator can see what the server actually sent)\nif (!result.data?.success) {\n    throw new Error(result.data?.errmsg ?? `yzj's server did not respond with the expected result: ${JSON.stringify(result.data)}`);\n}","handlingStrategy":"try-catch","validationCode":"// Ensure required YZJ fields are set\nif (!notification.yzjWebHookUrl) throw new Error(\"YZJ webhook URL is required\");\nif (!notification.yzjToken) throw new Error(\"YZJ token is required\");\ntry { new URL(notification.yzjWebHookUrl); } catch { throw new Error(\"yzjWebHookUrl is not a valid URL\"); }","typeGuard":"/** True when the YZJ body clearly indicates success. */\nfunction isYzjSuccess(data) {\n    return data && typeof data === \"object\" && data.success === true;\n}","tryCatchPattern":"try {\n    const result = await axios.post(url, params, config);\n    if (!isYzjSuccess(result.data)) {\n        throw new Error(result.data?.errmsg ?? `yzj unexpected response: ${JSON.stringify(result.data)}`);\n    }\n} catch (err) {\n    this.throwGeneralAxiosError(err);\n}","preventionTips":["Confirm yzjWebHookUrl is the current robot inbound URL.","Regenerate yzjToken when the robot is recreated.","Log the raw YZJ body during incidents to catch schema drift."],"tags":["yzj","notification-provider","api-response","config","diagnostics"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}