kestra-io/kestra · error · InvalidQueryFiltersException

Provided query filters are invalid: %s

Error message

Provided query filters are invalid: %s

What it means

Thrown by QueryFilter.validateQueryFilters() (wrapped in InvalidQueryFiltersException) when one or more filters reference an operation not supported by the target Resource for the given field. The validator walks each filter (recursing into node children) and collects every mismatch, then throws a single aggregate exception listing all errors. This enforces that only semantically valid filter combinations reach the backend query layer.

Source

Thrown at core/src/main/java/io/kestra/core/models/QueryFilter.java:899

        private static Operation toOperation(Op op) {
            return new Operation(op.name(), op.name());
        }
    }

    public record FieldOp(String name, String value, List<Operation> operations) {
    }

    public record Operation(String name, String value) {
    }

    public static void validateQueryFilters(List<QueryFilter> filters, Resource resource) {
        if (filters == null) {
            return;
        }
        List<String> errors = new ArrayList<>();
        filters.forEach(filter -> collectValidationErrors(filter, resource, errors));
        if (!errors.isEmpty()) {
            throw new InvalidQueryFiltersException(errors);
        }
    }

    private static void collectValidationErrors(QueryFilter filter, Resource resource, List<String> errors) {
        if (filter.isNode()) {
            filter.children().forEach(child -> collectValidationErrors(child, resource, errors));
            return;
        }
        if (!resource.supportedOp(filter.field()).contains(filter.operation())) {
            errors.add(
                "Operation %s is not supported for field %s. Supported operations are %s".formatted(
                    filter.operation(), filter.field().name(),
                    resource.supportedOp(filter.field()).stream().map(Op::name).collect(Collectors.joining(", "))
                )
            );
        }
        if (!resource.supportedField().contains(filter.field())) {
            errors.add(

View on GitHub (pinned to 823fada927)

Solutions

  1. Call Resource.supportedOp(field) to discover the valid operations for the target field before building the filter.
  2. Cross-check the field name against the resource's documented supported fields.
  3. If aggregating multiple filters, fix every reported error, not just the first.
  4. Update the client filter builder to constrain operation choices per-field.

Example fix

// before
filter: field=startDate, operation=EQUAL_TO
// InvalidQueryFiltersException: Operation EQUAL_TO not supported for startDate

// after
filter: field=startDate, operation=GREATER_THAN, value="2025-01-01"
Defensive patterns

Strategy: validation

Validate before calling

List<String> errors = new ArrayList<>();
filters.forEach(f -> collectValidationErrors(f, resource, errors));
if (!errors.isEmpty()) {
    throw new InvalidQueryFiltersException(errors);
}

Try / catch

try {
    QueryFilter.validateQueryFilters(filters, resource);
} catch (InvalidQueryFiltersException e) {
    return ResponseEntity.badRequest().body(Map.of("errors", e.getErrors()));
}

Prevention

When it happens

Trigger: Sending an EQUAL_TO operation on a field that only supports STARTS_WITH; using a date range operation on a non-date field; referencing a field that does not exist for the given Resource; mixing filters valid for executions on a logs/dashboards resource.

Common situations: Frontend exposes a generic filter UI without checking the resource's supported operations; API consumer copies a filter from one resource to another; a new operation was added to the enum but not to the resource's supportedOp map.

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/f420055adaed7264. Report an issue: GitHub.