louislam/uptime-kuma · warning · Error

JSON query returned the array ${truncatedResponse}, but a pr

Error message

JSON query returned the array ${truncatedResponse}, but a primitive value is required. Modify your query to return a single value via [0] to get the first element or use an aggregation like $count(), $sum() or $boolean().

What it means

Thrown by evaluateJsonQuery() when the post-JSONata response is an Array. The json-query monitor can only compare a single primitive value against the expected value, so an array result is rejected with guidance to project to one element or aggregate. The message embeds a truncated (<=25 chars) JSON of the array to aid debugging.

Source

Thrown at src/util.ts:717

        response = JSON.parse(data);
    } catch {
        response =
            (typeof data === "object" || typeof data === "number") && !Buffer.isBuffer(data) ? data : data.toString();
    }

    try {
        // If a JSON path is provided, pre-evaluate the data using it.
        response = jsonPath ? await jsonata(jsonPath).evaluate(response) : response;

        if (response === null || response === undefined) {
            throw new Error("Empty or undefined response. Check query syntax and response structure");
        }

        // Check for arrays: JSONata filter expressions like .[predicate] always return arrays
        if (Array.isArray(response)) {
            const responseStr = JSON.stringify(response);
            const truncatedResponse = responseStr.length > 25 ? responseStr.substring(0, 25) + "...]" : responseStr;
            throw new Error(
                "JSON query returned the array " +
                    truncatedResponse +
                    ", but a primitive value is required. " +
                    "Modify your query to return a single value via [0] to get the first element or use an aggregation like $count(), $sum() or $boolean()."
            );
        }

        if (typeof response === "object" || response instanceof Date || typeof response === "function") {
            throw new Error(
                `The post-JSON query evaluated response from the server is of type ${typeof response}, which cannot be directly compared to the expected value`
            );
        }

        // Perform the comparison logic using the chosen operator
        let jsonQueryExpression;
        switch (jsonPathOperator) {
            case ">":
            case ">=":

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Project to a single element: append `[0]` (or `[last]`) to the path to take the first/last match.
  2. Use a JSONata aggregation: `$count($.items[type='book'])`, `$sum($.orders[*].price)`, `$boolean($.items[type='book'])`.

Example fix

// before: monitor.jsonPath = "$.items[type='book']" -> array -> throws

// after: pick the first match
//   monitor.jsonPath = "$.items[type='book'][0]"
// or aggregate:
//   monitor.jsonPath = "$count($.items[type='book'])"
Defensive patterns

Strategy: validation

Validate before calling

const probe = await jsonata(jsonPath).evaluate(sample);
if (Array.isArray(probe)) throw new Error("Path returns an array; add [0] or an aggregation");

Type guard

const isPrimitive = (v) => v === null || v === undefined || ["string","number","boolean"].includes(typeof v);

Try / catch

try { await evaluateJsonQuery(data, path, op, expected); } catch (e) { if (/returned the array/.test(e.message)) { path += "[0]"; /* retry */ } else throw e; }

Prevention

When it happens

Trigger: monitor.jsonPath uses a wildcard or filter that yields multiple values: `$.users[*].name`, `$.items[type='book']`, `$..version` matching several nodes, `$.metrics[*]`. Any path returning more than one element lands here.

Common situations: User writes a JSONata filter expression expecting one match but several match; target payload shape changed from single object to array; predicate is too broad; user did not know wildcards return arrays.

Related errors


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