kestra-io/kestra · error · IllegalArgumentException
Unsupported operation for QUERY filter: {filter.operation()}
Error message
Unsupported operation for QUERY filter: {filter.operation()} What it means
The `SecretService.list()` method applies a `QUERY` filter from the caller. Only two operations are supported for this filter: `EQUALS` (substring contains, case-insensitive) and `NOT_EQUALS` (substring does not contain). If the filter's `operation()` is any other `QueryFilter.Op` value, an `IllegalArgumentException` is thrown. This is an API-consumer error indicating an unsupported query operation.
Source
Thrown at core/src/main/java/io/kestra/core/secret/SecretService.java:79
* Finds the secret in full mode, as a value plus metadata.
* The default returns the value with empty metadata. Multi-field secret managers override this to add metadata.
*/
public SecretObject findSecretObject(String tenantId, String namespace, String key) throws SecretNotFoundException, IOException {
return new SecretObject(findSecret(tenantId, namespace, key));
}
public ArrayListTotal<META> list(Pageable pageable, String tenantId, List<QueryFilter> filters) throws IOException {
final Predicate<String> queryPredicate = filters.stream()
.filter(filter -> QueryFilter.Field.QUERY.equals(filter.field()) && filter.value() != null)
.findFirst()
.map(filter ->
{
if (QueryFilter.Op.EQUALS.equals(filter.operation())) {
return (Predicate<String>) s -> Strings.CI.contains(s, (String) filter.value());
} else if (QueryFilter.Op.NOT_EQUALS.equals(filter.operation())) {
return (Predicate<String>) s -> !Strings.CI.contains(s, (String) filter.value());
} else {
throw new IllegalArgumentException("Unsupported operation for QUERY filter: " + filter.operation());
}
})
.orElse(s -> true);
//noinspection unchecked
return ArrayListTotal.of(
pageable,
decodedSecrets.keySet().stream().filter(queryPredicate).map(s -> (META) s).toList()
);
}
public Map<String, Set<String>> inheritedSecrets(String tenantId, String namespace) throws IOException {
return Map.of(namespace, decodedSecrets.keySet());
}
public Map<String, Set<String>> ownAndInheritedSecrets(String tenantId, String namespace) throws IOException {
return inheritedSecrets(tenantId, namespace);
}View on GitHub (pinned to 823fada927)
Solutions
- Use only `EQUALS` or `NOT_EQUALS` as the operation for a `QUERY` field filter when listing secrets.
- If you need prefix or suffix matching, filter the returned list client-side.
- If this is an SDK bug, report it — the API contract for secret listing should match.
Example fix
// before filters.add(QueryFilter.of(QueryFilter.Field.QUERY, QueryFilter.Op.STARTS_WITH, "AWS")); // after filters.add(QueryFilter.of(QueryFilter.Field.QUERY, QueryFilter.Op.EQUALS, "AWS"));
Defensive patterns
Strategy: validation
Validate before calling
// Validate the query filter operation before calling list()
import io.kestra.core.models.QueryFilter;
public static void validateSecretQueryFilters(List<QueryFilter> filters) {
for (QueryFilter f : filters) {
if (QueryFilter.Field.QUERY.equals(f.field())) {
if (f.operation() != QueryFilter.Op.EQUALS && f.operation() != QueryFilter.Op.NOT_EQUALS) {
throw new IllegalArgumentException(
"QUERY filter only supports EQUALS and NOT_EQUALS, got: " + f.operation());
}
}
}
} Type guard
import { QueryFilter } from './types';
function isSupportedSecretQueryOp(op: QueryFilter.Op): boolean {
return op === 'EQUALS' || op === 'NOT_EQUALS';
} Try / catch
try {
secretService.list(pageable, tenantId, filters);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Unsupported operation for QUERY filter")) {
// strip unsupported filters and retry with EQUALS
filters = filters.stream()
.filter(f -> !QueryFilter.Field.QUERY.equals(f.field())
|| f.operation() == QueryFilter.Op.EQUALS
|| f.operation() == QueryFilter.Op.NOT_EQUALS)
.toList();
secretService.list(pageable, tenantId, filters);
} else throw e;
} Prevention
- Only use EQUALS and NOT_EQUALS for QUERY filters when listing secrets.
- Build a reusable filter-validation utility for all API calls.
- Document the supported operations per filter field in the API contract.
When it happens
Trigger: A REST API or SDK call to list secrets passes a `QueryFilter` with `field=QUERY` and an operation like `STARTS_WITH`, `GREATER_THAN`, or `IN`. The backend secret listing only supports substring matching.
Common situations: A frontend or SDK consumer tries to use a generic filter operation that is valid for other resource types but not implemented for secret listing. A version change introduced a new `QueryFilter.Op` enum value that is not yet handled here.
Related errors
- The 'secret' function expects an argument 'key'.
- Migration script [<scriptId>] has no checksum to repair.
- Cannot repair migration script [<scriptId>] because it has n
- Cannot import file of type <type>
- QueryFilter must be either a leaf (field + operation) or a n
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/1b2d5d086b34a98a.
Report an issue: GitHub.