{"record":{"id":"2055cd842936c591","repo":"spring-projects/spring-ai","slug":"query-rewrite-result-is-null-empty-returning-the","errorCode":null,"errorMessage":"Query rewrite result is null/empty. Returning the input query unchanged.","messagePattern":"Query rewrite result is null/empty\\. Returning the input query unchanged\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spring-ai-rag/src/main/java/org/springframework/ai/rag/preretrieval/query/transformation/RewriteQueryTransformer.java","lineNumber":90,"sourceCode":"\t}\n\n\t@Override\n\tpublic Query transform(Query query) {\n\t\tAssert.notNull(query, \"query cannot be null\");\n\n\t\tif (logger.isDebugEnabled()) {\n\t\t\tlogger.debug(\"Rewriting query to optimize for querying a \" + this.targetSearchSystem + \".\");\n\t\t}\n\n\t\tvar rewrittenQueryText = this.chatClient.prompt()\n\t\t\t.user(user -> user.text(this.promptTemplate.getTemplate())\n\t\t\t\t.param(\"target\", this.targetSearchSystem)\n\t\t\t\t.param(\"query\", query.text()))\n\t\t\t.call()\n\t\t\t.content();\n\n\t\tif (!StringUtils.hasText(rewrittenQueryText)) {\n\t\t\tlogger.warn(\"Query rewrite result is null/empty. Returning the input query unchanged.\");\n\t\t\treturn query;\n\t\t}\n\n\t\treturn query.mutate().text(rewrittenQueryText).build();\n\t}\n\n\tpublic static Builder builder() {\n\t\treturn new Builder();\n\t}\n\n\tpublic static final class Builder {\n\n\t\tprivate ChatClient.@Nullable Builder chatClientBuilder;\n\n\t\tprivate @Nullable PromptTemplate promptTemplate;\n\n\t\tprivate @Nullable String targetSearchSystem;\n","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-rag/src/main/java/org/springframework/ai/rag/preretrieval/query/transformation/RewriteQueryTransformer.java#L72-L108","documentation":"RewriteQueryTransformer asks a ChatModel (via a prompt template) to rewrite the user query for a target search system. When the model returns a null or blank string instead of usable text, the transformer logs this warning and returns the original query unchanged rather than corrupting the retrieval pipeline with empty input. It is a graceful-degradation path, not a hard failure.","triggerScenarios":"Calling transform(Query) on a RewriteQueryTransformer whose underlying ChatModel call returns null content or whitespace-only text — e.g. the model refuses, hits a content filter, returns an empty completion, or the prompt template fails to elicit a rewrite.","commonSituations":"Using a small/weak model that produces empty responses; aggressive content filtering on the provider (e.g. safety filters on Azure OpenAI); low maxTokens truncating output; the rewrite prompt confusing the model so it answers with nothing; provider outages returning empty bodies.","solutions":["Check the model's raw response outside the transformer — if empty, inspect provider logs/content-filter flags and adjust the prompt to demand a rewritten query with no commentary.","Use a stronger model (e.g. OpenAiChatOptions with a more capable model) or increase maxTokens for the rewrite call.","Ensure the prompt template in RewriteQueryTransformer.defaultPromptTemplate or your custom one instructs the model to always output a query.","If unchanged queries are acceptable, keep the default behavior — the input query is returned safely and retrieval continues."],"exampleFix":"// before: default model returning empty rewrites\nQueryTransformer transformer = RewriteQueryTransformer.builder()\n    .chatClientBuilder(weakModelClientBuilder)\n    .build();\n// after: capable model + explicit instruction\nQueryTransformer transformer = RewriteQueryTransformer.builder()\n    .chatClientBuilder(strongModelClientBuilder)\n    .promptTemplate(new PromptTemplate(\"Rewrite the following query for {target}. Output ONLY the rewritten query:\\n{query}\"))\n    .build();","handlingStrategy":"validation","validationCode":"if (query != null && StringUtils.hasText(query.text())) {\n    // safe to pass to transformer; result falls back to input if rewrite is empty\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a model known to comply with rewrite prompts and test its empty-response rate.","Set adequate maxTokens for the rewrite call.","Monitor provider content-filter metrics for your prompts.","Treat the returned original query as a signal to log and audit rewrite quality."],"tags":["rag","query-transformation","empty-response","graceful-degradation"],"backgroundTag":"empty-api-response","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}