louislam/uptime-kuma · error · Error
${heartbeat.msg}, but keyword is ${keywordFound ? "present"
Error message
${heartbeat.msg}, but keyword is ${keywordFound ? "present" : "not"} in [${data}] What it means
Thrown by handleKeywordForHTTP when keyword presence does not match the invert setting. With invertKeyword off, the keyword must be present; with invert on, it must be absent. The response is HTML/whitespace-stripped and truncated to 47 chars before being included so the message stays readable.
Source
Thrown at server/monitor-types/globalping.js:399
/**
* Handles keyword search for HTTP monitors.
* @param {Monitor} monitor - The monitor object.
* @param {Heartbeat} heartbeat - The heartbeat object.
* @param {Result} result - The result object.
* @param {Probe} probe - The probe object.
* @returns {Promise<void>}
*/
async handleKeywordForHTTP(monitor, heartbeat, result, probe) {
let data = result.rawOutput;
let keywordFound = data.includes(monitor.keyword);
if (keywordFound === Boolean(monitor.invertKeyword)) {
data = data.replace(/<[^>]*>?|[\n\r]|\s+/gm, " ").trim();
if (data.length > 50) {
data = data.substring(0, 47) + "...";
}
throw new Error(
heartbeat.msg + ", but keyword is " + (keywordFound ? "present" : "not") + " in [" + data + "]"
);
}
heartbeat.msg += ", keyword " + (keywordFound ? "is" : "not") + " found";
heartbeat.status = UP;
}
/**
* Handles JSON query for HTTP monitors.
* @param {Monitor} monitor - The monitor object.
* @param {Heartbeat} heartbeat - The heartbeat object.
* @param {Result} result - The result object.
* @param {Probe} probe - The probe object.
* @returns {Promise<void>} A promise that resolves when the JSON query is handled.
*/
async handleJSONQueryForHTTP(monitor, heartbeat, result, probe) {
const { status, response } = await evaluateJsonQuery(View on GitHub (pinned to 6b5ea01557)
Solutions
- Open the target URL and confirm whether the keyword actually appears in the response body
- Re-check the invertKeyword toggle — invert means the monitor is UP when the keyword is ABSENT
- Pick a stable, unique keyword that survives layout changes
- Remember the displayed response is stripped of tags/whitespace and truncated to ~47 chars
Example fix
// before: invert on, keyword appears -> DOWN monitor.invertKeyword = true; monitor.keyword = "maintenance"; // after: invert off when you want the keyword to be present monitor.invertKeyword = false;
Defensive patterns
Strategy: validation
Validate before calling
// Confirm keyword semantics before running
if (!monitor.keyword || monitor.keyword.length === 0) {
throw new Error("HTTP keyword monitor has no keyword set");
}
// invertKeyword: when true, monitor is UP only if keyword is ABSENT
const expectPresent = !monitor.invertKeyword; Try / catch
// The thrown message already truncates the body; preserve it for alerting
if (keywordFound === Boolean(monitor.invertKeyword)) {
throw new Error(heartbeat.msg + ", but keyword is " + (keywordFound ? "present" : "not") + " in [" + data + "]");
} Prevention
- Choose a stable, unique keyword unlikely to change with layout updates
- Double-check the invert toggle semantics before saving
- Periodically verify the keyword still appears in the live response
When it happens
Trigger: keywordFound === Boolean(monitor.invertKeyword). If invert is false and keyword absent -> throw 'not present'; if invert is true and keyword present -> throw 'present'. This is the classic keyword-mismatch path for Globalping HTTP keyword monitors.
Common situations: Target page content changed so the keyword no longer appears, the keyword was set against transient content, invertKeyword is accidentally enabled/disabled, or the keyword matches part of HTML markup that gets stripped before the check re-runs.
Related errors
- Status code ${result.statusCode} not accepted. Output: ${res
- No record matched.
- JSON query does not pass (comparing ${response} ${monitor.js
- ${bean.msg}, but keyword is ${present|not} in [${data}]
- Headers must be valid JSON: ${e.message}
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/c25c3044272c4164.
Report an issue: GitHub.