louislam/uptime-kuma · error · Error

Conditions not met - Topic

Error message

Conditions not met - Topic: ${messageTopic}; Message: ${receivedMessage}

What it means

Thrown by MqttMonitorType.checkConditions when evaluateExpressionGroup returns false for the condition data {topic, message, json_value}. This is the conditions-system path; the message body and topic are exposed to user-defined operators, and json_value is the stringified JSONata result (empty string when jsonPath is unset or JSON parsing failed silently).

Solutions

  1. Confirm the published payload is valid JSON when monitor.jsonPath is set (a non-JSON payload silently blanks json_value).
  2. Verify the condition references only exposed variables: 'topic', 'message', 'json_value'.
  3. Test the condition expression against the actual topic/message/json_value triple using evaluateExpressionGroup directly.
  4. If matching raw text, use the 'message' variable with the right string operator; switch json_value conditions to 'message' contains if JSON is unreliable.

Example fix

// before: condition variable='value' operator='==' value='ON'  (no such variable)
// after:  condition variable='json_value' operator='==' value='ON'
// and ensure payload is JSON {"state":"ON"} so json_value is populated
Defensive patterns

Strategy: try-catch

Validate before calling

const { evaluateExpressionGroup } = require('../server/monitor-conditions/evaluator');
function dryRunConditions(group, topic, message, jsonValue) {
  return evaluateExpressionGroup(group, { topic, message, json_value: jsonValue ?? '' });
}

Type guard

function conditionsExposeOnlyAllowedVars(group) {
  const allowed = new Set(['topic','message','json_value']);
  return group.children.every(c => allowed.has(c.variable));
}

Try / catch

try { await mqttMonitor.checkConditions(monitor, heartbeat, topic, msg, group); }
catch (e) { if (/Conditions not met/.test(e.message)) { heartbeat.status = DOWN; heartbeat.msg = e.message; } else throw e; }

Prevention

When it happens

Trigger: monitor.conditions parses to a non-empty ConditionExpressionGroup (hasConditions true), mqttAsync resolves with a message, and the evaluated group over {topic, message, json_value} is false. Also fires when monitor.jsonPath is set but receivedMessage is not valid JSON — the inner try/catch swallows the parse error, json_value becomes '', and conditions referencing json_value then fail.

Common situations: Condition uses the wrong variable name (e.g. 'value' instead of 'json_value'); operator chosen expects a number but json_value is empty because JSON parse failed; regex/case-sensitive string operator against a differently-cased payload; jsonPath typo producing empty json_value.

Related errors


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

Appendix: source

Thrown at server/monitor-types/mqtt.js:125

                jsonValue = await expression.evaluate(parsedMessage);
            } catch (e) {
                // JSON parsing failed, jsonValue remains null
            }
        }

        const conditionData = {
            topic: messageTopic,
            message: receivedMessage,
            json_value: jsonValue?.toString() ?? "",
        };

        const conditionsResult = evaluateExpressionGroup(conditions, conditionData);

        if (conditionsResult) {
            heartbeat.msg = `Topic: ${messageTopic}; Message: ${receivedMessage}`;
            heartbeat.status = UP;
        } else {
            throw new Error(`Conditions not met - Topic: ${messageTopic}; Message: ${receivedMessage}`);
        }
    }

    /**
     * Connect to MQTT Broker, subscribe to topic and receive message as String
     * @param {string} hostname Hostname / address of machine to test
     * @param {string} topic MQTT topic
     * @param {object} options MQTT options. Contains port, username,
     * password, websocketPath and interval (interval defaults to 20)
     * @returns {Promise<string>} Received MQTT message
     */
    mqttAsync(hostname, topic, options = {}) {
        return new Promise((resolve, reject) => {
            const { port, username, password, websocketPath, interval = 20 } = options;

            // Adds MQTT protocol to the hostname if not already present
            if (!/^(?:http|mqtt|ws)s?:\/\//.test(hostname)) {
                hostname = "mqtt://" + hostname;

View on GitHub (pinned to 6b5ea01557)