louislam/uptime-kuma · warning · Error

Invalid duration: ${duration}

Error message

Invalid duration: ${duration}

What it means

Thrown by UptimeCalculator.getDataByDuration(duration) when `duration.slice(0, -1)` (everything except the last character) does not match `^[0-9]+$`. The parser expects exactly a positive integer literal followed by a single unit letter. Any non-digit characters in the numeric portion, an empty numeric portion, decimals, or a leading sign are rejected.

Source

Thrown at server/uptime-calculator.js:779

                default:
                    throw new Error("Invalid type");
            }
        }

        return result;
    }

    /**
     * Get the uptime data for given duration.
     * @param {string} duration  A string with a number and a unit (m,h,d,w,M,y), such as 24h, 30d, 1y.
     * @returns {UptimeDataResult} UptimeDataResult
     * @throws {Error} Invalid duration / Unsupported unit
     */
    getDataByDuration(duration) {
        const durationNumStr = duration.slice(0, -1);

        if (!/^[0-9]+$/.test(durationNumStr)) {
            throw new Error(`Invalid duration: ${duration}`);
        }
        const num = Number(durationNumStr);
        const unit = duration.slice(-1);

        switch (unit) {
            case "m":
                return this.getData(num, "minute");
            case "h":
                return this.getData(num, "hour");
            case "d":
                return this.getData(num, "day");
            case "w":
                return this.getData(7 * num, "day");
            case "M":
                return this.getData(30 * num, "day");
            case "y":
                return this.getData(365 * num, "day");
            default:

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Normalize the duration to `<integer><unit>` (e.g. "24h", "30d", "1y") before calling getDataByDuration.
  2. Strip whitespace and reject decimals/signs upstream: parse with `/^(\d+)([mhdwMy])$/`.
  3. If you accept bare numbers, append the default unit yourself (as api-router does for hours).
  4. Return a 400 from badge routes when the duration does not match the canonical pattern.

Example fix

// before
const up = uptimeCalculator.getDataByDuration("1.5h"); // -> "1.5" fails /^[0-9]+$/

// after
const m = /^(\d+)([mhdwMy])$/.exec(String(duration).trim());
if (!m) throw new Error(`Bad duration: ${duration}`);
const up = uptimeCalculator.getDataByDuration(m[1] + m[2]);
Defensive patterns

Strategy: validation

Validate before calling

const m = /^(\d+)([mhdwMy])$/.exec(String(duration).trim());
if (!m) throw new Error("Duration must be <int><unit>");
getDataByDuration(m[1] + m[2]);

Type guard

const isCanonicalDuration = (v) => typeof v === "string" && /^\d+[mhdwMy]$/.test(v.trim());

Try / catch

try { getDataByDuration(d); } catch (e) { if (/Invalid duration/.test(e.message)) { /* normalize then retry */ } throw e; }

Prevention

When it happens

Trigger: Calling getDataByDuration with: "abc" (numeric portion "ab"), "h" (numeric portion ""), "1.5h" ("1.5" fails), "-3d" ("-3" fails), "" (slicing empty string), " 24h" (leading space), "24 h" (space before unit). Note api-router.js:245-247 normalizes a bare integer like "24" to "24h" first, so a pure-number badge duration does NOT reach this error; only malformed strings do.

Common situations: Badge URL with a malformed duration segment (`/api/badge/:id/status/abc` → "abc" slice "ab" fails); user-typed duration with a decimal ("0.5h"); trailing whitespace or BOM in the duration; copy-paste of a duration with the wrong unit convention.

Related errors


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