alibaba/spring-ai-alibaba · error · IllegalStateException
Failed to delete documents by filter
Error message
Failed to delete documents by filter
What it means
If the delete-by-query request executed in doDelete(Filter.Expression) throws for any reason, it is wrapped and rethrown as IllegalStateException("Failed to delete documents by filter", e) with the original exception as the cause. The index exists, but the query delete itself failed.
Solutions
- Inspect the wrapped cause (e.getCause()) for the concrete Elasticsearch error (parse_error, 429, 503, etc.).
- Validate that the Filter.Expression converts to a valid query (log getElasticsearchQueryString(filterExpression)).
- Check cluster health and retry if the failure was due to shard unavailability or throttling.
- Simplify or correct the filter expression; verify field names exist in the index mapping.
Example fix
// before
catch (Exception e) { throw new IllegalStateException("Failed to delete documents by filter", e); }
// after
catch (Exception e) {
logger.error("deleteByQuery failed, query={}", getElasticsearchQueryString(filterExpression), e);
throw new IllegalStateException("Failed to delete documents by filter: " + e.getMessage(), e);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Java: sanity-check the converted query before executing
String qs = new ElasticsearchAiSearchFilterExpressionConverter().convertExpression(filterExpression);
if (qs == null || qs.isBlank()) throw new IllegalArgumentException("filter converts to empty query"); Try / catch
try { vectorStore.delete(filterExpression); } catch (IllegalStateException e) {
Throwable root = e.getCause();
log.error("delete-by-query failed: {}", root == null ? "unknown" : root.getMessage(), root);
if (isTransient(root)) retryAfterBackoff(); else throw e;
} Prevention
- Log the Elasticsearch query string generated from the filter for validation.
- Test filter expressions against a staging index mapping.
- Handle 429/503 with backoff retries; they are common under load.
- Verify field names in Filter.Expression match index mappings.
When it happens
Trigger: Calling VectorStore.delete(Filter.Expression) when the deleteByQuery call fails: malformed/unconvertible filter expression producing an invalid query_string, query parse errors, cluster/shard unavailability, timeouts, or permission errors.
Common situations: Filter expressions that translate to invalid Elasticsearch query_string syntax; red cluster status; delete-by-query hitting the 429 or 503 due to load; missing field mappings making the query invalid.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Delete operation failed
- hybrid alpha should be between 0 ~ 1.
- Index not found
- Unsupported search type:
- Elastic search index name must be provided
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/bb49bcdc5a5a5063.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStore.java:240
if (bulkRequest(bulkRequestBuilder.build()).errors()) {
throw new IllegalStateException("Delete operation failed");
}
}
@Override
public void doDelete(Filter.Expression filterExpression) {
// For the index to be present, either it must be pre-created or set the
// initializeSchema to true.
if (!indexExists()) {
throw new IllegalArgumentException("Index not found");
}
try {
this.elasticsearchClient.deleteByQuery(d -> d.index(this.options.getIndexName())
.query(q -> q.queryString(qs -> qs.query(getElasticsearchQueryString(filterExpression)))));
}
catch (Exception e) {
throw new IllegalStateException("Failed to delete documents by filter", e);
}
}
private BulkResponse bulkRequest(BulkRequest bulkRequest) {
try {
return this.elasticsearchClient.bulk(bulkRequest);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public List<Document> doSimilaritySearch(SearchRequest searchRequest) {
Assert.notNull(searchRequest, "The search request must not be null.");
return switch (searchRequest.getSearchType()) {
case SEMANTIC -> searchBySemantic(searchRequest);View on GitHub (pinned to f82da0b50f)