{"record":{"id":"d2edccf901b8033d","repo":"louislam/uptime-kuma","slug":"query-evaluation-returned-undefined-check-query-s","errorCode":null,"errorMessage":"Query evaluation returned undefined. Check query syntax and the structure of the response data","messagePattern":"Query evaluation returned undefined\\. Check query syntax and the structure of the response data","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/util.ts","lineNumber":761,"sourceCode":"            case \"==\":\n                jsonQueryExpression = \"$.value = $.expected\";\n                break;\n            case \"contains\":\n                jsonQueryExpression = \"$contains($.value, $.expected)\";\n                break;\n            default:\n                throw new Error(`Invalid condition ${jsonPathOperator}`);\n        }\n\n        // Evaluate the JSON Query Expression\n        const expression = jsonata(jsonQueryExpression);\n        const status = await expression.evaluate({\n            value: response.toString(),\n            expected: expectedValue.toString(),\n        });\n\n        if (status === undefined) {\n            throw new Error(\n                \"Query evaluation returned undefined. Check query syntax and the structure of the response data\"\n            );\n        }\n\n        return {\n            status, // The evaluation of the json query\n            response, // The response from the server or result from initial json-query evaluation\n        };\n    } catch (err: any) {\n        response = JSON.stringify(response); // Ensure the response is treated as a string for the console\n        response = response && response.length > 50 ? `${response.substring(0, 100)}… (truncated)` : response; // Truncate long responses to the console\n        throw new Error(`Error evaluating JSON query: ${err.message}. Response from server was: ${response}`);\n    }\n}\n\n// these types will have domain expiry support via the specified field\nexport const TYPES_WITH_DOMAIN_EXPIRY_SUPPORT_VIA_FIELD = {\n    http: \"url\",","sourceCodeStart":743,"sourceCodeEnd":779,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/src/util.ts#L743-L779","documentation":"Thrown by evaluateJsonQuery() after evaluating the compiled JSONata comparison expression when `status === undefined`. Unlike null/false, undefined means JSONata could not produce a result at all — typically a type error such as `$number(...)` on a non-numeric value, or `$contains` on a non-string. The function treats this distinctly from a legitimate false result.","triggerScenarios":"Using a comparison operator (>, >=, <, <=) where the selected value is non-numeric, so `$number($.value)` returns undefined; using `contains` where either value or expected is not a string; JSONata silently returning undefined due to type coercion failure inside the generated expression `$number($.value) <op> $number($.expected)`.","commonSituations":"expectedValue left blank for a numeric operator; the field is a string where a number was expected; locale-formatted numbers (\"1.234,56\") that `$number` rejects; null/empty value reaching the comparator after passing earlier null checks (it can't — null is caught earlier — but a JSONata intermediate can still be undefined).","solutions":["Match the operator to the value type: numeric operators require numeric values, `contains` requires strings.","Provide a concrete expectedValue of the right type for the chosen operator.","Coerce the value inside the path: `monitor.jsonPath = \"$number($.field)\"` for numeric comparison.","If the value may be missing, default it in JSONata: `($ := $.field; $count($match($, /\\d+/)) > 0 ? $number($) : 0)`."],"exampleFix":"// before: value is \"12.5%\" (string), operator \">\", expected \"90\"\n//   $number(\"12.5%\") -> undefined -> status undefined -> throws\n\n// after: strip the unit in the path, then compare\n//   monitor.jsonPath = \"$number($replace($.field, '%', ''))\"\n//   operator \">\", expectedValue \"90\"","handlingStrategy":"validation","validationCode":"const probe = await jsonata(`$number(${jsonPath})`).evaluate(sample);\nif (probe === undefined && [\">\", \">=\", \"<\", \"<=\"].includes(operator)) throw new Error(\"Value not numeric\");","typeGuard":"const isNumericCompareSafe = (v, op) => ![\">\", \">=\", \"<\", \"<=\"].includes(op) || (typeof v === \"number\" && !Number.isNaN(v));","tryCatchPattern":"try { await evaluateJsonQuery(data, path, op, expected); } catch (e) { if (/returned undefined/.test(e.message)) { path = \"$number(\" + path + \")\"; /* retry */ } else throw e; }","preventionTips":["Match operator type to value type.","Coerce in the path with $number(...) for numeric comparisons.","Always provide a concrete expectedValue."],"tags":["json-query","jsonata","monitor","validation","typescript","uptime-kuma"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}