louislam/uptime-kuma · error · Error

${bean.msg}, but keyword is ${present|not} in [${data}]

Error message

${bean.msg}, but keyword is ${present|not} in [${data}]

What it means

Thrown by the keyword monitor when keyword presence contradicts the invert setting. The response is HTML-stripped, whitespace-collapsed, and truncated to 50 chars so the heartbeat message shows a preview of what was actually received.

Source

Thrown at server/model/monitor.js:700

                        bean.status = UP;
                    } else if (this.type === "keyword") {
                        let data = res.data;

                        // Convert to string for object/array
                        if (typeof data !== "string") {
                            data = JSON.stringify(data);
                        }

                        let keywordFound = data.includes(this.keyword);
                        if (keywordFound === !this.isInvertKeyword()) {
                            bean.msg += ", keyword " + (keywordFound ? "is" : "not") + " found";
                            bean.status = UP;
                        } else {
                            data = data.replace(/<[^>]*>?|[\n\r]|\s+/gm, " ").trim();
                            if (data.length > 50) {
                                data = data.substring(0, 47) + "...";
                            }
                            throw new Error(
                                bean.msg +
                                    ", but keyword is " +
                                    (keywordFound ? "present" : "not") +
                                    " in [" +
                                    data +
                                    "]"
                            );
                        }
                    } else if (this.type === "json-query") {
                        let data = res.data;

                        const { status, response } = await evaluateJsonQuery(
                            data,
                            this.jsonPath,
                            this.jsonPathOperator,
                            this.expectedValue
                        );

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Open the monitored URL and confirm the keyword still appears in the HTML source
  2. If using invert mode, re-read the logic: DOWN is recorded when the keyword IS found
  3. For SPAs, monitor the backing API JSON endpoint instead of the HTML shell
  4. Check for character/encoding variations (curly quotes, entities) in the keyword
Defensive patterns

Strategy: validation

Validate before calling

// Verify keyword expectation against a sample response before relying on the monitor
function keywordWillPass(sampleText, keyword, invert) {
  const found = sampleText.includes(keyword);
  return found === !invert;
}

Try / catch

// The throw is internal to the beat loop and surfaces as a DOWN heartbeat;
// read bean.msg/bean.status from the heartbeat result rather than catching.
const beat = await runMonitorBeat(id);
if (beat.status !== UP) console.warn(beat.msg);

Prevention

When it happens

Trigger: HTTP keyword monitor where data.includes(keyword) does not match isInvertKeyword(): keyword absent while not inverted, or keyword present while inverted.

Common situations: Target page content changed or removed the keyword; keyword typo; SPA returns an empty shell HTML so the keyword never appears; confusion about invert semantics.

Related errors


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