{"record":{"id":"cd1b63ace8b9dcdf","repo":"louislam/uptime-kuma","slug":"bean-msg-but-keyword-is-present-not-in-d","errorCode":null,"errorMessage":"${bean.msg}, but keyword is ${present|not} in [${data}]","messagePattern":"(.+?), but keyword is (.+?) in \\[(.+?)\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/model/monitor.js","lineNumber":700,"sourceCode":"                        bean.status = UP;\n                    } else if (this.type === \"keyword\") {\n                        let data = res.data;\n\n                        // Convert to string for object/array\n                        if (typeof data !== \"string\") {\n                            data = JSON.stringify(data);\n                        }\n\n                        let keywordFound = data.includes(this.keyword);\n                        if (keywordFound === !this.isInvertKeyword()) {\n                            bean.msg += \", keyword \" + (keywordFound ? \"is\" : \"not\") + \" found\";\n                            bean.status = UP;\n                        } else {\n                            data = data.replace(/<[^>]*>?|[\\n\\r]|\\s+/gm, \" \").trim();\n                            if (data.length > 50) {\n                                data = data.substring(0, 47) + \"...\";\n                            }\n                            throw new Error(\n                                bean.msg +\n                                    \", but keyword is \" +\n                                    (keywordFound ? \"present\" : \"not\") +\n                                    \" in [\" +\n                                    data +\n                                    \"]\"\n                            );\n                        }\n                    } else if (this.type === \"json-query\") {\n                        let data = res.data;\n\n                        const { status, response } = await evaluateJsonQuery(\n                            data,\n                            this.jsonPath,\n                            this.jsonPathOperator,\n                            this.expectedValue\n                        );\n","sourceCodeStart":682,"sourceCodeEnd":718,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/model/monitor.js#L682-L718","documentation":"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.","triggerScenarios":"HTTP keyword monitor where data.includes(keyword) does not match isInvertKeyword(): keyword absent while not inverted, or keyword present while inverted.","commonSituations":"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.","solutions":["Open the monitored URL and confirm the keyword still appears in the HTML source","If using invert mode, re-read the logic: DOWN is recorded when the keyword IS found","For SPAs, monitor the backing API JSON endpoint instead of the HTML shell","Check for character/encoding variations (curly quotes, entities) in the keyword"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify keyword expectation against a sample response before relying on the monitor\nfunction keywordWillPass(sampleText, keyword, invert) {\n  const found = sampleText.includes(keyword);\n  return found === !invert;\n}","typeGuard":null,"tryCatchPattern":"// The throw is internal to the beat loop and surfaces as a DOWN heartbeat;\n// read bean.msg/bean.status from the heartbeat result rather than catching.\nconst beat = await runMonitorBeat(id);\nif (beat.status !== UP) console.warn(beat.msg);","preventionTips":["Confirm the keyword exists in the raw HTML source (not just the rendered DOM) when setting up the monitor","Re-read invert semantics: invert alerts when the keyword IS found"],"tags":["keyword","http","monitoring"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}