louislam/uptime-kuma · error · Error
yzj's server did not respond with the expected result
Error message
yzj's server did not respond with the expected result
What it means
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.
Source
Thrown at server/notification-providers/yzj.js:33
if (heartbeatJSON !== null) {
msg = `${this.statusToString(heartbeatJSON["status"])} ${monitorJSON["name"]} \n> ${heartbeatJSON["msg"]}\n> Time (${heartbeatJSON["timezone"]}): ${heartbeatJSON["localDateTime"]}`;
}
let config = {
headers: {
"Content-Type": "application/json",
},
};
const params = {
content: msg,
};
// yzjtype=0 => general robot
const url = `${notification.yzjWebHookUrl}?yzjtype=0&yzjtoken=${notification.yzjToken}`;
config = this.getAxiosConfigWithProxy(config);
const result = await axios.post(url, params, config);
if (!result.data?.success) {
throw new Error(result.data?.errmsg ?? "yzj's server did not respond with the expected result");
}
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
/**
* Convert status constant to string
* @param {string} status The status constant
* @returns {string} status
*/
statusToString(status) {
switch (status) {
case DOWN:
return "❌";
case UP:
return "✅";View on GitHub (pinned to 6b5ea01557)
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.
Example fix
// before
if (!result.data?.success) {
throw new Error(result.data?.errmsg ?? "yzj's server did not respond with the expected result");
}
// after (preserve the raw body so the operator can see what the server actually sent)
if (!result.data?.success) {
throw new Error(result.data?.errmsg ?? `yzj's server did not respond with the expected result: ${JSON.stringify(result.data)}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure required YZJ fields are set
if (!notification.yzjWebHookUrl) throw new Error("YZJ webhook URL is required");
if (!notification.yzjToken) throw new Error("YZJ token is required");
try { new URL(notification.yzjWebHookUrl); } catch { throw new Error("yzjWebHookUrl is not a valid URL"); } Type guard
/** True when the YZJ body clearly indicates success. */
function isYzjSuccess(data) {
return data && typeof data === "object" && data.success === true;
} Try / catch
try {
const result = await axios.post(url, params, config);
if (!isYzjSuccess(result.data)) {
throw new Error(result.data?.errmsg ?? `yzj unexpected response: ${JSON.stringify(result.data)}`);
}
} catch (err) {
this.throwGeneralAxiosError(err);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: yzjWebHookUrl pointing at an outdated endpoint, yzjToken expired, YZJ robot disabled, or upstream API version change dropping the success/errmsg fields.
Related errors
- SMSEagle API returned error: ${resp.data}
- SMSEagle API returned an empty response
- SMSEagle API returned error: ${JSON.stringify(resp.data)}
- Invalid VK API response
- Additional Headers is not a valid JSON
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/5d6a1aab172b1413.
Report an issue: GitHub.