{"record":{"id":"e0ab97577581d554","repo":"spring-projects/spring-ai","slug":"chatclientresponse-is-missing-required-json-output","errorCode":null,"errorMessage":"ChatClientResponse is missing required json output for validation.","messagePattern":"ChatClientResponse is missing required json output for validation\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/StructuredOutputValidationAdvisor.java","lineNumber":184,"sourceCode":"\t\t\t\t\t\t\t.build());\n\n\t\t\t\t\tprocessedChatClientRequest = chatClientRequest.mutate().prompt(augmentedPrompt).build();\n\t\t\t\t}\n\t\t\t\telse if (logger.isDebugEnabled()) {\n\t\t\t\t\tlogger.debug(\"JSON validation succeeded\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn usageAccumulator.applyAccumulatedUsage(Objects.requireNonNull(chatClientResponse));\n\t}\n\n\tprivate SchemaValidation validateOutputSchema(ChatClientResponse chatClientResponse, int leftAttemptsCounter) {\n\n\t\tif (chatClientResponse.chatResponse() == null || chatClientResponse.chatResponse().getResult() == null\n\t\t\t\t|| chatClientResponse.chatResponse().getResult().getOutput().getText() == null) {\n\n\t\t\tlogger.warn(\"ChatClientResponse is missing required json output for validation.\");\n\t\t\treturn SchemaValidation.failed(\"Missing required json output for validation.\");\n\t\t}\n\n\t\t// TODO: should we consider validation for multiple results?\n\t\tString json = chatClientResponse.chatResponse().getResult().getOutput().getText();\n\n\t\tif (logger.isDebugEnabled()) {\n\t\t\tlogger.debug(\"Validating JSON output against schema. Attempts left: \" + leftAttemptsCounter);\n\t\t}\n\n\t\treturn validateJsonText(json);\n\t}\n\n\tprivate SchemaValidation validateJsonText(String json) {\n\t\tif (json.isBlank()) {\n\t\t\treturn SchemaValidation.failed(\"Empty JSON output for validation.\");\n\t\t}\n\t\ttry {","sourceCodeStart":166,"sourceCodeEnd":202,"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#L166-L202","documentation":"StructuredOutputValidationAdvisor.validateOutputSchema extracts the JSON text from the ChatClientResponse for schema validation. If the response, its ChatResponse, its single result, or the output text is null, there is nothing to validate, so it logs a warning and returns SchemaValidation.failed — which drives the retry/error path instead of throwing a NPE.","triggerScenarios":"Calling through the advisor pipeline when the model call produced no ChatResponse or produced a generation whose output has no text — e.g. empty completion (see empty-choices case), streamed empty response, or an error short-circuit in the chain.","commonSituations":"Upstream model returning empty results (content filter, proxy issue); the advisor applied to a call that didn't produce assistant text; misconfigured chain where the ChatResponse was never set.","solutions":["Check why the ChatResponse/text is empty — often the model returned no choices (enable DEBUG logging, inspect the raw API response)","Ensure the advisor runs on a normal chat completion flow that produces text output","Rephrase the prompt or check content filtering if the model returns an empty completion","Handle SchemaValidation failure in the response flow and retry the request"],"exampleFix":"// before\nString json = response.chatResponse().getResult().getOutput().getText();\nvalidate(json);\n// after\nChatResponse cr = response.chatResponse();\nif (cr == null || cr.getResult() == null || cr.getResult().getOutput().getText() == null) {\n    throw new IllegalStateException(\"Model produced no text to validate\");\n}","handlingStrategy":"type-guard","validationCode":"ChatResponse cr = response.chatResponse();\nString json = (cr != null && cr.getResult() != null && cr.getResult().getOutput() != null)\n    ? cr.getResult().getOutput().getText() : null;\nif (json == null || json.isBlank()) throw new IllegalStateException(\"no text output\");","typeGuard":"static boolean hasValidatableText(ChatClientResponse r) {\n    return r != null && r.chatResponse() != null && r.chatResponse().getResult() != null\n        && r.chatResponse().getResult().getOutput() != null\n        && r.chatResponse().getResult().getOutput().getText() != null;\n}","tryCatchPattern":null,"preventionTips":["Ensure the model call actually returns text before applying the advisor","Investigate empty-choice responses upstream","Don't apply the advisor to calls that short-circuit without a ChatResponse"],"tags":["advisor","structured-output","null-response"],"backgroundTag":"empty-response-body","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"}