{"record":{"id":"3be9100be65b7eb2","repo":"spring-projects/spring-ai","slug":"either-outputtype-or-outputjsonschema-must-be-set","errorCode":null,"errorMessage":"Either outputType or outputJsonSchema must be set.","messagePattern":"Either outputType or outputJsonSchema must be set\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/StructuredOutputValidationAdvisor.java","lineNumber":345,"sourceCode":"\t\tpublic Builder jsonMapper(JsonMapper jsonMapper) {\n\t\t\tthis.jsonMapper = jsonMapper;\n\t\t\treturn this;\n\t\t}\n\n\t\t/**\n\t\t * Builds the StructuredOutputValidationAdvisor.\n\t\t * @return a new StructuredOutputValidationAdvisor instance\n\t\t * @throws IllegalArgumentException if neither outputType nor outputJsonSchema is\n\t\t * set, or if both are set\n\t\t */\n\t\tpublic StructuredOutputValidationAdvisor build() {\n\n\t\t\tif (StringUtils.hasText(this.outputJsonSchema) && this.outputType != null) {\n\t\t\t\tthrow new IllegalArgumentException(\"Only outputType or outputJsonSchema can be set, not both.\");\n\t\t\t}\n\n\t\t\tif (!StringUtils.hasText(this.outputJsonSchema) && this.outputType == null) {\n\t\t\t\tthrow new IllegalArgumentException(\"Either outputType or outputJsonSchema must be set.\");\n\t\t\t}\n\n\t\t\tif (this.outputType != null) {\n\t\t\t\tthis.outputJsonSchema = JsonSchemaGenerator.generateForType(this.outputType);\n\t\t\t}\n\n\t\t\treturn new StructuredOutputValidationAdvisor(this.advisorOrder,\n\t\t\t\t\tObjects.requireNonNull(this.outputJsonSchema), this.maxRepeatAttempts, this.jsonMapper);\n\t\t}\n\n\t}\n\n\tprivate record SchemaValidation(boolean success, String errorMessage) {\n\n\t\tprivate static SchemaValidation passed() {\n\t\t\treturn new SchemaValidation(true, \"\");\n\t\t}\n","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/StructuredOutputValidationAdvisor.java#L327-L363","documentation":"StructuredOutputValidationAdvisor.Builder.build() requires an output specification: neither outputType nor outputJsonSchema was set, so build() throws IllegalArgumentException('Either outputType or outputJsonSchema must be set.'). Without one, the advisor cannot know what schema to validate model output against.","triggerScenarios":"Calling StructuredOutputValidationAdvisor.builder().build() (or advisor() on a chain) without first calling outputType(...) or outputJsonSchema(...).","commonSituations":"Forgotten configuration when wiring the advisor into the advisor chain, refactoring that removed outputType but didn't add outputJsonSchema, or building the advisor conditionally where the branch setting the schema never executed.","solutions":["Call .outputType(YourResultType.class) to generate the schema from a Java type.","Or call .outputJsonSchema(validSchemaString) with an explicit JSON Schema.","Check that conditional code paths that set the output spec actually run before build()."],"exampleFix":"// before\nStructuredOutputValidationAdvisor.builder().build();\n// after\nStructuredOutputValidationAdvisor.builder()\n    .outputType(MyRecord.class)\n    .build();","handlingStrategy":"validation","validationCode":"StructuredOutputValidationAdvisor.Builder b = StructuredOutputValidationAdvisor.builder();\nif (resultType != null) b.outputType(resultType); else if (schema != null) b.outputJsonSchema(schema);\nelse throw new IllegalStateException(\"advisor needs outputType or outputJsonSchema\");","typeGuard":null,"tryCatchPattern":"try { advisorBuilder.build(); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Either outputType or outputJsonSchema\")) { /* set the output spec */ } throw e; }","preventionTips":["Always set outputType as the simplest default when a result type is known.","Check conditional branches that build the advisor actually set the output spec.","Add a unit test constructing the advisor from your production config."],"tags":["builder","missing-argument","structured-output","spring-ai"],"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-14T11:17:12.474Z"}