provectus/kafka-ui · error · ValidationException

Unexpected script result

Error message

Unexpected script result: %s, Boolean should be returned instead

What it means

MessageFilters.test evaluates a user-supplied Groovy filter script per message and requires the script to return a Boolean. If the compiled script evaluates to anything else (String, Map, null, Integer), a ValidationException is thrown telling the user to return a Boolean.

Solutions

  1. Make the script's last evaluated expression a boolean, e.g. `return value != null`
  2. Wrap non-boolean logic in a comparison: `record.key == 'x'` instead of `record.key`
  3. Test the script on a single message first; remember null results also fail

Example fix

// before (script)
value?.name
// after (script)
value?.name == 'my-event'
Defensive patterns

Strategy: validation

Validate before calling

function validateFilterScript(src) {
  const result = evalCompiledPreview(src); // run against a sample message in a sandbox
  if (typeof result !== 'boolean') {
    throw new Error('Filter must evaluate to a boolean, got: ' + typeof result);
  }
}

Type guard

const isBooleanResult = (r) => typeof r === 'boolean';

Try / catch

try {
  const filter = MessageFilters.compile(script);
} catch (ValidationException e) {
  if (e.getMessage().contains('Boolean should be returned')) {
    showHint('End your script with a boolean expression, e.g. value != null');
  }
}

Prevention

When it happens

Trigger: Entering a filter in the UI 'Filter messages' dialog whose last expression doesn't evaluate to true/false, e.g. `value != null` returning a String, or a script ending with a statement that returns null.

Common situations: Scripts copied from examples that print or return objects; forgetting `return true/false` or a final boolean expression; using `record.value == null` styles that yield null in edge cases; treating it like a predicate language where truthiness coercion happens (Groovy is not used that way here).

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08). Data as JSON: /api/errors/9f5a9e9716384892. Report an issue: GitHub.

Appendix: source

Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/emitter/MessageFilters.java:62

    var jsonSlurper = new JsonSlurper();
    return new Predicate<TopicMessageDTO>() {
      @SneakyThrows
      @Override
      public boolean test(TopicMessageDTO msg) {
        var bindings = engine.createBindings();
        bindings.put("partition", msg.getPartition());
        bindings.put("offset", msg.getOffset());
        bindings.put("timestampMs", msg.getTimestamp().toInstant().toEpochMilli());
        bindings.put("keyAsText", msg.getKey());
        bindings.put("valueAsText", msg.getContent());
        bindings.put("headers", msg.getHeaders());
        bindings.put("key", parseToJsonOrReturnAsIs(jsonSlurper, msg.getKey()));
        bindings.put("value", parseToJsonOrReturnAsIs(jsonSlurper, msg.getContent()));
        var result = compiledScript.eval(bindings);
        if (result instanceof Boolean) {
          return (Boolean) result;
        } else {
          throw new ValidationException(
              "Unexpected script result: %s, Boolean should be returned instead".formatted(result));
        }
      }
    };
  }

  @Nullable
  private static Object parseToJsonOrReturnAsIs(JsonSlurper parser, @Nullable String str) {
    if (str == null) {
      return null;
    }
    try {
      return parser.parseText(str);
    } catch (Exception e) {
      return str;
    }
  }

View on GitHub (pinned to 83b5a60cc0)