louislam/uptime-kuma · error · Error
Invalid domain
Error message
Invalid domain
What it means
Thrown by StatusPage.updateDomainNameList when an element of the domainNameList array is not a string. Each entry is stored verbatim in status_page_cname.domain, so non-string values would break CNAME matching and DNS routing.
Source
Thrown at server/model/status_page.js:396
/**
* Update list of domain names
* @param {string[]} domainNameList List of status page domains
* @returns {Promise<void>}
*/
async updateDomainNameList(domainNameList) {
if (!Array.isArray(domainNameList)) {
throw new Error("Invalid array");
}
let trx = await R.begin();
await trx.exec("DELETE FROM status_page_cname WHERE status_page_id = ?", [this.id]);
try {
for (let domain of domainNameList) {
if (typeof domain !== "string") {
throw new Error("Invalid domain");
}
if (domain.trim() === "") {
continue;
}
// If the domain name is used in another status page, delete it
await trx.exec("DELETE FROM status_page_cname WHERE domain = ?", [domain]);
let mapping = trx.dispense("status_page_cname");
mapping.status_page_id = this.id;
mapping.domain = domain;
await trx.store(mapping);
}
await trx.commit();
} catch (error) {
await trx.rollback();
throw error;View on GitHub (pinned to 6b5ea01557)
Solutions
- Ensure every element is a string; coerce with String(x) or filter non-strings out beforehand.
- If your source data uses objects, map them: list.map(o => o.domain).
- Validate with list.every(d => typeof d === "string") before calling.
Example fix
// before
await statusPage.updateDomainNameList([ { domain: "status.example.com" } ]);
// after
await statusPage.updateDomainNameList([ "status.example.com" ]); Defensive patterns
Strategy: type-guard
Validate before calling
function normalizeDomains(list) {
return list.map(d => typeof d === "object" && d ? d.domain : d).filter(d => typeof d === "string");
} Type guard
function isStringArray(list) {
return Array.isArray(list) && list.every(d => typeof d === "string");
} Try / catch
try {
await statusPage.updateDomainNameList(list);
} catch (e) {
if (/Invalid domain/.test(e.message)) return badRequest("every domain must be a string");
throw e;
} Prevention
- Validate with list.every(d => typeof d === "string") before the call.
- Reject object-wrapped domain payloads at the API schema layer.
When it happens
Trigger: Call updateDomainNameList with [123, "x"], [null], [{domain:"x"}], or [true]. The check fires inside the per-domain loop after the array guard but before the empty-trim short-circuit.
Common situations: Mixed-type arrays from loosely-typed API clients. Object-wrapped domains from an import format that uses {domain: "..."}. Numeric IDs accidentally placed in the domain field.
Related errors
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/34e44971603243eb.
Report an issue: GitHub.