spring-projects/spring-ai · warning
Query expansion result does not contain the requested
Error message
Query expansion result does not contain the requested ${numberOfQueries} variants. Returning the input query unchanged. What it means
After splitting the model response on newlines, MultiQueryExpander checks that the number of variants equals numberOfQueries; if the list is empty or the count mismatches, it warns and returns the original query unchanged. LLMs often return fewer, more, or merged lines, so strict count matching frequently trips.
Solutions
- Relax expectations: newer versions remove strict count matching — upgrade spring-ai-rag.
- Use a prompt template that demands exactly N lines with no numbering or extra text.
- Post-filter blank lines yourself by supplying a custom prompt and parsing tolerant input.
- Reduce numberOfQueries or test with a model that follows line-count instructions reliably.
Example fix
// before — strict count triggers fallback often
.prompt(DEFAULT_USER_TEXT)
// "Generate {number} search queries..."
// after — template that enforces one query per line, no numbering
MultiQueryExpander.builder()
.chatClient(chatClient)
.prompt("Generate exactly {number} search queries, one per line, no numbering, no extra text for: {query}")
.numberOfQueries(3)
.build(); Defensive patterns
Strategy: fallback
Validate before calling
String response = model.call(prompt);
long lines = response == null ? 0 : Arrays.stream(response.split("\n")).filter(s -> !s.isBlank()).count();
if (lines != expectedNumberOfQueries) logger.warn("Expansion returned {} of {} lines", lines, expectedNumberOfQueries); Try / catch
List<Query> expanded = expander.expand(query);
if (expanded.size() == 1 && expanded.get(0).equals(query)) {
logger.info("Expansion fallback; proceeding with original query");
} Prevention
- Prompt for exactly N lines with no numbering or commentary.
- Upgrade spring-ai-rag if available (strict count check was relaxed).
- Avoid reasoning-style models for expansion.
- Keep numberOfQueries modest (2-5) so models comply.
When it happens
Trigger: expand() -> response.split("\n") yields a list whose size differs from this.numberOfQueries (or is empty).
Common situations: Model returns numbered or blank-line-separated queries causing miscount; model returns 1 line instead of N; extra explanation lines around the queries; reasoning models returning prose.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- Query expansion result is null. Returning the input query…
- keywordCount will be ignored as keywordsTemplate is set.
- No prompt methods found in the provided prompt objects
- No prompt methods found in the provided prompt objects
- No prompt methods found in the provided prompt objects
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/9059f2c3a9b1f0b2.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-rag/src/main/java/org/springframework/ai/rag/preretrieval/query/expansion/MultiQueryExpander.java:120
}
var response = this.chatClient.prompt()
.user(user -> user.text(this.promptTemplate.getTemplate())
.param("number", this.numberOfQueries)
.param("query", query.text()))
.call()
.content();
if (response == null) {
logger.warn("Query expansion result is null. Returning the input query unchanged.");
return List.of(query);
}
var queryVariants = Arrays.asList(response.split("\n"));
if (CollectionUtils.isEmpty(queryVariants) || this.numberOfQueries != queryVariants.size()) {
if (logger.isWarnEnabled()) {
logger.warn("Query expansion result does not contain the requested " + this.numberOfQueries
+ " variants. Returning the input query unchanged.");
}
return List.of(query);
}
var queries = queryVariants.stream()
.filter(StringUtils::hasText)
.map(queryText -> query.mutate().text(queryText).build())
.collect(Collectors.toList());
if (this.includeOriginal) {
logger.debug("Including the original query in the result");
queries.add(0, query);
}
return queries;
}
View on GitHub (pinned to 98a7beda4f)