louislam/uptime-kuma · warning · Error

The maximum number of days is 365

Error message

The maximum number of days is 365

What it means

Thrown by UptimeCalculator.getData(num, type) when `type === "day" && num > 365`. Bounds daily-resolution data to one year. Notably, the weekly/monthly/yearly expansions in getDataByDuration delegate to day type (7*num, 30*num, 365*num), so large compound durations hit this gate too.

Source

Thrown at server/uptime-calculator.js:571

        }
        throw new Error("Invalid status");
    }

    /**
     * @param {number} num the number of data points which are expected to be returned
     * @param {"day" | "hour" | "minute"} type the type of data which is expected to be returned
     * @returns {UptimeDataResult} UptimeDataResult
     * @throws {Error} The maximum number of minutes greater than 1440
     */
    getData(num, type = "day") {
        if (type === "hour" && num > 24 * 30) {
            throw new Error("The maximum number of hours is 720");
        }
        if (type === "minute" && num > 24 * 60) {
            throw new Error("The maximum number of minutes is 1440");
        }
        if (type === "day" && num > 365) {
            throw new Error("The maximum number of days is 365");
        }
        // Get the current time period key based on the type
        let key = this.getKey(this.getCurrentDate(), type);

        let total = {
            up: 0,
            down: 0,
        };

        let totalPing = 0;
        let endTimestamp;

        // Get the earliest timestamp of the required period based on the type
        switch (type) {
            case "day":
                endTimestamp = key - 86400 * (num - 1);
                break;
            case "hour":

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Keep day-type ranges at or below 365; for multi-year display, aggregate manually or cap to 365.
  2. Avoid compound durations that expand past 365 days: "2y", "13M", "54w" all throw.
  3. If you need "all history", query the max supported window ("1y" / "365d") and document the cap.
  4. Clamp the numeric portion before calling getData/ByDuration.

Example fix

// before
const up = uptimeCalculator.getDataByDuration("2y"); // -> getData(730,"day") -> throws

// after
const up = uptimeCalculator.getDataByDuration("1y"); // 365 days, at the limit
// or clamp:
const up = uptimeCalculator.getData(Math.min(num, 365), "day");
Defensive patterns

Strategy: validation

Validate before calling

if (type === "day") num = Math.min(num, 365);

Type guard

const withinDayLimit = (n) => typeof n === "number" && n > 0 && n <= 365;

Try / catch

try { getData(n, "day"); } catch (e) { if (/maximum number of days/.test(e.message)) getData(365, "day"); else throw e; }

Prevention

When it happens

Trigger: Direct getData(num, "day") with num > 365; getDataByDuration("Nd") with N > 365; getDataByDuration("2y") → getData(365*2=730, "day") → throws; getDataByDuration("13M") → getData(30*13=390, "day") → throws; getDataByDuration("54w") → getData(7*54=378, "day") → throws. The yearly badge (1y = 365) sits exactly at the limit and does not throw.

Common situations: Badge URL with multi-year duration (e.g. "2y") expecting it to work; status page configured with a long monthly window that compounds past 365 days; misunderstanding that weekly/monthly/yearly are converted to days internally and inherit the 365-day cap.

Related errors


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/380e3bcede51c73b. Report an issue: GitHub.