{"record":{"id":"f1a1fd13c0c6bba5","repo":"louislam/uptime-kuma","slug":"error-in-output-res-stderr-tostring","errorCode":null,"errorMessage":"Error in output: ${res.stderr.toString()}","messagePattern":"Error in output: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/monitor-types/tailscale-ping.js","lineNumber":35,"sourceCode":"            throw new Error(`Error checking Tailscale ping: ${err}`);\n        }\n    }\n\n    /**\n     * Runs the Tailscale ping command to the given URL.\n     * @param {string} hostname The hostname to ping.\n     * @param {number} interval Interval to send ping\n     * @returns {Promise<string>} A Promise that resolves to the output of the Tailscale ping command\n     * @throws Will throw an error if the command execution encounters any error.\n     */\n    async runTailscalePing(hostname, interval) {\n        let timeout = interval * 1000 * 0.8;\n        let res = await childProcessAsync.spawn(\"tailscale\", [\"ping\", \"--c\", \"1\", hostname], {\n            timeout: timeout,\n            encoding: \"utf8\",\n        });\n        if (res.stderr && res.stderr.toString() && res.code !== 0) {\n            throw new Error(`Error in output: ${res.stderr.toString()}`);\n        }\n        if (res.stdout && res.stdout.toString()) {\n            return res.stdout.toString();\n        } else {\n            throw new Error(\"No output from Tailscale ping\");\n        }\n    }\n\n    /**\n     * Parses the output of the Tailscale ping command to update the heartbeat.\n     * @param {string} tailscaleOutput The output of the Tailscale ping command.\n     * @param {object} heartbeat The heartbeat object to update.\n     * @returns {void}\n     * @throws Will throw an eror if the output contains any unexpected string.\n     */\n    parseTailscaleOutput(tailscaleOutput, heartbeat) {\n        let lines = tailscaleOutput.split(\"\\n\");\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/monitor-types/tailscale-ping.js#L17-L53","documentation":"Thrown by runTailscalePing() after the spawn of 'tailscale ping' completed (did not throw) but wrote to stderr and exited with a non-zero code. promisify-child-process resolves the spawn with {stdout, stderr, code}; this branch converts a failed exit into an explicit error using the stderr text.","triggerScenarios":"Produced when 'tailscale ping --c 1 <hostname>' exits non-zero and prints to stderr: not logged in, tailscaled unreachable, permission denied, unknown flag, or a tailscale daemon error.","commonSituations":"tailscale daemon not running; the Uptime-Kuma process user cannot invoke tailscale; tailscale version that does not support '--c' syntax; auth expired; node offline in the tailnet; running inside a container without tailscaled sidecar.","solutions":["Run 'tailscale ping --c 1 <hostname>' manually as the Uptime-Kuma user to reproduce and read the stderr message.","Ensure tailscaled is running and the host is logged in ('tailscale status' should list peers).","Confirm the tailscale CLI version supports the flags used; upgrade or adjust the invocation if '--c' is not accepted.","If running in containers, make sure the tailscale socket/daemon is reachable from the Uptime-Kuma container."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function isNonZeroExit(res) { return res && res.code !== 0 && res.stderr && res.stderr.toString().trim().length > 0; }","typeGuard":"function hasStderr(res) { return !!res?.stderr && res.stderr.toString().trim().length > 0; }","tryCatchPattern":"if (isNonZeroExit(res)) { heartbeat.status = DOWN; heartbeat.msg = res.stderr.toString().trim(); return; }","preventionTips":["Run 'tailscale status' before relying on tailscale-ping monitors.","Keep the tailscale CLI version compatible with the flags used.","Ensure the Uptime-Kuma user can invoke tailscale."],"tags":["tailscale","spawn","stderr","vpn"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}