{"record":{"id":"69fa7d2406c96203","repo":"louislam/uptime-kuma","slug":"the-maximum-number-of-hours-is-720","errorCode":null,"errorMessage":"The maximum number of hours is 720","messagePattern":"The maximum number of hours is 720","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"server/uptime-calculator.js","lineNumber":565,"sourceCode":"            case UP:\n            case MAINTENANCE:\n                return UP;\n            case DOWN:\n            case PENDING:\n                return DOWN;\n        }\n        throw new Error(\"Invalid status\");\n    }\n\n    /**\n     * @param {number} num the number of data points which are expected to be returned\n     * @param {\"day\" | \"hour\" | \"minute\"} type the type of data which is expected to be returned\n     * @returns {UptimeDataResult} UptimeDataResult\n     * @throws {Error} The maximum number of minutes greater than 1440\n     */\n    getData(num, type = \"day\") {\n        if (type === \"hour\" && num > 24 * 30) {\n            throw new Error(\"The maximum number of hours is 720\");\n        }\n        if (type === \"minute\" && num > 24 * 60) {\n            throw new Error(\"The maximum number of minutes is 1440\");\n        }\n        if (type === \"day\" && num > 365) {\n            throw new Error(\"The maximum number of days is 365\");\n        }\n        // Get the current time period key based on the type\n        let key = this.getKey(this.getCurrentDate(), type);\n\n        let total = {\n            up: 0,\n            down: 0,\n        };\n\n        let totalPing = 0;\n        let endTimestamp;\n","sourceCodeStart":547,"sourceCodeEnd":583,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/uptime-calculator.js#L547-L583","documentation":"Thrown by UptimeCalculator.getData(num, type) when `type === \"hour\" && num > 24 * 30` (720). Bounds the amount of hourly data points returned because the calculator only retains 30 days of hourly stats (`statHourlyKeepDay = 30`). Requesting more would silently return incomplete data, so the API fails fast instead.","triggerScenarios":"Reached directly via getData(num, \"hour\") with num > 720, or indirectly via getDataByDuration(\"Nh\") where N > 720 (e.g. badge URL `/api/badge/:id/status/1000` normalizes to \"1000h\" because a pure number is treated as hours at api-router.js:245-247). Also via weekly/monthly/yearly expansions that land on hour type — but those use day type, so not here.","commonSituations":"Badge URL with a large bare number interpreted as hours; custom client requesting a year of hourly uptime; scripted load test passing arbitrary period values; confusion between minutes/hours/days units in the duration string.","solutions":["Cap the requested duration to the supported maximum: for hours use <= 720 (30 days).","Switch to day type for longer ranges: request \"30d\" / \"365d\" instead of \"720h\"+.","If building a badge URL, pass an explicit unit (e.g. 30d) rather than a bare number.","Validate the duration string client-side against the m/h/d/w/M/y limits before calling the API."],"exampleFix":"// before\nconst up = uptimeCalculator.getData(1000, \"hour\");\n\n// after\nconst hours = Math.min(num, 720);\nconst up = uptimeCalculator.getData(hours, \"hour\");\n// or for longer ranges:\nconst up = uptimeCalculator.getData(Math.min(days, 365), \"day\");","handlingStrategy":"validation","validationCode":"if (type === \"hour\") num = Math.min(num, 720);","typeGuard":"const withinHourLimit = (n) => typeof n === \"number\" && n > 0 && n <= 720;","tryCatchPattern":"try { getData(n, \"hour\"); } catch (e) { if (/maximum number of hours/.test(e.message)) getData(720, \"hour\"); else throw e; }","preventionTips":["Clamp hour requests to 720 at the call site.","Prefer day type for windows over 30 days.","Always pass an explicit unit on badge URLs."],"tags":["uptime-calculator","limits","badge","validation","uptime-kuma"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}