{"record":{"id":"edc785e87d25f241","repo":"spring-projects/spring-ai","slug":"the-following-placeholders-must-be-present-in-the","errorCode":null,"errorMessage":"The following placeholders must be present in the prompt template: %s","messagePattern":"The following placeholders must be present in the prompt template: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-rag/src/main/java/org/springframework/ai/rag/util/PromptAssert.java","lineNumber":54,"sourceCode":"\n\t/**\n\t * Assert that the given prompt template contains the required placeholders.\n\t * @param promptTemplate the prompt template to check\n\t * @param placeholders the placeholders that must be present in the prompt template\n\t */\n\tpublic static void templateHasRequiredPlaceholders(PromptTemplate promptTemplate, String... placeholders) {\n\t\tAssert.notNull(promptTemplate, \"promptTemplate cannot be null\");\n\t\tAssert.notEmpty(placeholders, \"placeholders cannot be null or empty\");\n\n\t\tList<String> missingPlaceholders = new ArrayList<>();\n\t\tfor (String placeholder : placeholders) {\n\t\t\tif (!promptTemplate.getTemplate().contains(placeholder)) {\n\t\t\t\tmissingPlaceholders.add(placeholder);\n\t\t\t}\n\t\t}\n\n\t\tif (!missingPlaceholders.isEmpty()) {\n\t\t\tthrow new IllegalArgumentException(\"The following placeholders must be present in the prompt template: %s\"\n\t\t\t\t.formatted(String.join(\",\", missingPlaceholders)));\n\t\t}\n\t}\n\n}\n","sourceCodeStart":36,"sourceCodeEnd":60,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-rag/src/main/java/org/springframework/ai/rag/util/PromptAssert.java#L36-L60","documentation":"PromptAssert.templateHasRequiredPlaceholders validates that every placeholder the caller declares is literally present in the prompt template's text. If any declared placeholder is missing from the template string, an IllegalArgumentException lists all missing placeholders.","triggerScenarios":"Calling templateHasRequiredPlaceholders (used by RAG components like RetrievalAugmentationAdvisor's query transformer/rag prompt) with a template that lacks one of the required variables, e.g. {query} or {question_answer_context} removed or renamed during prompt customization.","commonSituations":"Users editing the built-in RAG prompt templates and deleting or misspelling required placeholders like 'question_answer_context'; custom prompts that use different variable names; delimiters differing ({var} vs {{var}}) so the literal text check fails.","solutions":["Re-add the missing placeholder to the template exactly as declared (e.g. {question_answer_context})","Fix placeholder spelling/casing to match the required name","Use the library's default template if unsure which placeholders are mandatory","If using a different template syntax, ensure the raw template text contains the placeholder string verbatim"],"exampleFix":"// before\nString template = \"Answer the question: {user_query}\"; // missing required placeholder\n// after\nString template = \"Answer the question: {query} using context: {question_answer_context}\";","handlingStrategy":"validation","validationCode":"List<String> missing = Stream.of(\"query\", \"question_answer_context\")\n    .filter(p -> !template.getTemplate().contains(p)).toList();\nif (!missing.isEmpty()) throw new IllegalStateException(\"Template missing: \" + missing);","typeGuard":null,"tryCatchPattern":"try { advisor.advise(query, context); } catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"placeholders must be present\")) { /* restore placeholders in template */ }\n}","preventionTips":["Start from the library's default RAG template and only append text, never remove placeholders","Add a unit test asserting required placeholders exist in custom templates","Watch out when switching template engines — placeholder syntax must still match literally"],"tags":["rag","prompt-template","validation"],"backgroundTag":"missing-required-argument","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"}