alibaba/spring-ai-alibaba · error · IllegalArgumentException
Unsupported search type:
Error message
Unsupported search type:
What it means
doSimilaritySearch dispatches on SearchRequest.getSearchType() via a switch over SEMANTIC, FULL_TEXT, and HYBRID; any other value throws IllegalArgumentException("Unsupported search type: ..."). Since Java switch over an enum covers all constants, this default arm mainly fires for null or unexpected/custom search types.
Solutions
- Explicitly set SearchRequest.builder().searchType(SearchType.SEMANTIC) (or FULL_TEXT/HYBRID) when constructing the request.
- Check that the SearchRequest class version matches the vector store module (version skew).
- Ensure searchType is not null before calling similaritySearch.
- Only use search types documented for this Elasticsearch vector store.
Example fix
// before
SearchRequest request = SearchRequest.builder().query("q").topK(5).build();
// after
SearchRequest request = SearchRequest.builder().query("q").topK(5)
.searchType(SearchType.SEMANTIC)
.build(); Defensive patterns
Strategy: validation
Validate before calling
// Java
SearchType t = searchRequest.getSearchType();
if (t != SearchType.SEMANTIC && t != SearchType.FULL_TEXT && t != SearchType.HYBRID) {
throw new IllegalArgumentException("search type must be SEMANTIC, FULL_TEXT, or HYBRID: " + t);
} Type guard
static boolean isSupported(SearchRequest req) {
return req != null && req.getSearchType() != null
&& (req.getSearchType() == SearchType.SEMANTIC
|| req.getSearchType() == SearchType.FULL_TEXT
|| req.getSearchType() == SearchType.HYBRID);
} Try / catch
try { return vectorStore.similaritySearch(request); } catch (IllegalArgumentException e) {
if (String.valueOf(e.getMessage()).startsWith("Unsupported search type")) { log.error("bad searchType: {}", request.getSearchType()); }
throw e;
} Prevention
- Always set searchType explicitly in SearchRequest builders.
- Keep SearchRequest/VectorStore dependencies on the same version to avoid enum skew.
- Reject unsupported search types at API boundary before hitting the store.
- Add unit tests per search type you intend to use.
When it happens
Trigger: Calling VectorStore.similaritySearch(SearchRequest) with a SearchRequest whose searchType is not one of the supported SEMANTIC/FULL_TEXT/HYBRID values — e.g. null searchType or a type introduced in a different version of the SearchRequest model.
Common situations: Building SearchRequest without explicitly setting searchType and getting an unexpected default; version skew between the SearchRequest class and this vector store implementation; copy-paste of a search type name from another vector store.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Delete operation failed
- Failed to delete documents by filter
- hybrid alpha should be between 0 ~ 1.
- Index not found
- Elastic search index name must be provided
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/eba55887a0d79031.
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:261
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);
case FULL_TEXT -> searchByFullText(searchRequest);
case HYBRID -> searchByHybrid(searchRequest);
default -> throw new IllegalArgumentException("Unsupported search type: " + searchRequest.getSearchType());
};
}
private String getElasticsearchQueryString(Filter.Expression filterExpression) {
return Objects.isNull(filterExpression) ? "*"
: this.filterExpressionConverter.convertExpression(filterExpression);
}
private Document toDocument(Hit<Document> hit, SearchType searchType) {
Document document = hit.source();
Document.Builder documentBuilder = document.mutate();
if (hit.score() != null) {
documentBuilder.metadata(DocumentMetadata.DISTANCE.value(), 1 - normalizeSimilarityScore(hit.score()));
if (searchType == SearchType.FULL_TEXT) {
documentBuilder.score(1 - hit.score());
}View on GitHub (pinned to f82da0b50f)