{"record":{"id":"6ea6f87ae196637f","repo":"spring-projects/spring-ai","slug":"only-one-of-template-or-resource-can-be-set-6ea6f8","errorCode":null,"errorMessage":"Only one of template or resource can be set","messagePattern":"Only one of template or resource can be set","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-model/src/main/java/org/springframework/ai/chat/prompt/SystemPromptTemplate.java","lineNumber":99,"sourceCode":"\t\t}\n\n\t\tpublic Builder variables(Map<String, Object> variables) {\n\t\t\tAssert.notNull(variables, \"variables cannot be null\");\n\t\t\tAssert.noNullElements(variables.keySet(), \"variables keys cannot be null\");\n\t\t\tthis.variables = variables;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder renderer(TemplateRenderer renderer) {\n\t\t\tAssert.notNull(renderer, \"renderer cannot be null\");\n\t\t\tthis.renderer = renderer;\n\t\t\treturn this;\n\t\t}\n\n\t\t@Override\n\t\tpublic SystemPromptTemplate build() {\n\t\t\tif (this.template != null && this.resource != null) {\n\t\t\t\tthrow new IllegalArgumentException(\"Only one of template or resource can be set\");\n\t\t\t}\n\t\t\telse if (this.resource != null) {\n\t\t\t\treturn new SystemPromptTemplate(this.resource, this.variables, this.renderer);\n\t\t\t}\n\t\t\telse if (this.template != null) {\n\t\t\t\treturn new SystemPromptTemplate(this.template, this.variables, this.renderer);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new IllegalStateException(\"Neither template nor resource is set\");\n\t\t\t}\n\t\t}\n\n\t}\n\n}\n","sourceCodeStart":81,"sourceCodeEnd":115,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-model/src/main/java/org/springframework/ai/chat/prompt/SystemPromptTemplate.java#L81-L115","documentation":"SystemPromptTemplate.Builder.build() throws this IllegalArgumentException when both an inline template and a Resource are set. Like PromptTemplate, the system-prompt variant requires exactly one template source.","triggerScenarios":"SystemPromptTemplate.builder().template(\"...\").resource(resource)...build() — both sources configured on the same builder.","commonSituations":"Builder chains that set a default inline system prompt and then also attach a resource override; refactored code that kept a stale .template(...) call.","solutions":["Remove either the .template(...) or the .resource(...) call so exactly one source remains.","Select the source conditionally (resource if configured, else inline) before building.","Use separate builder instances for the two variants."],"exampleFix":"// before\nSystemPromptTemplate.builder().template(\"You are helpful\").resource(res).build();\n// after\nSystemPromptTemplate.builder().resource(res).build();","handlingStrategy":"validation","validationCode":"if (b.templateSet && b.resourceSet) throw new IllegalStateException(\"Set only one of template or resource for SystemPromptTemplate\");","typeGuard":null,"tryCatchPattern":"try { return builder.build(); } catch (IllegalArgumentException e) { logger.error(\"both template and resource set on SystemPromptTemplate\", e); }","preventionTips":["Choose exactly one system-prompt source per builder","Avoid builder reuse that accumulates both setters","Cover system-prompt construction with unit tests"],"tags":["builder","mutually-exclusive","system-prompt"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}