spring-projects/spring-ai · error · IllegalArgumentException

Unsupported response format type:

Error message

Unsupported response format type: 

What it means

createRequest only maps ResponseFormat.Type values TEXT, JSON_OBJECT, and JSON_SCHEMA to OpenAI response_format parameters. If requestOptions.getResponseFormat() has any other ResponseFormat.Type enum value, no mapping exists and this IllegalArgumentException is thrown. The library deliberately fails fast because sending an unmapped response format type would be silently dropped or produce an API error downstream.

Source

Thrown at models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java:795

						.builder();
					jsonSchemaBuilder.name("json_schema");
					Boolean strict = responseFormat.getStrict();
					jsonSchemaBuilder.strict(strict != null ? strict : true);

					ResponseFormatJsonSchema.JsonSchema.Schema schema = objectMapper.readValue(jsonSchemaString,
							ResponseFormatJsonSchema.JsonSchema.Schema.class);

					jsonSchemaBuilder.schema(schema);

					builder.responseFormat(
							ResponseFormatJsonSchema.builder().jsonSchema(jsonSchemaBuilder.build()).build());
				}
				catch (Exception e) {
					throw new IllegalArgumentException("Failed to parse JSON schema: " + jsonSchemaString, e);
				}
			}
			else {
				throw new IllegalArgumentException("Unsupported response format type: " + responseFormat.getType());
			}
		}
		if (requestOptions.getSeed() != null) {
			builder.seed(requestOptions.getSeed());
		}
		if (requestOptions.getStop() != null && !requestOptions.getStop().isEmpty()) {
			if (requestOptions.getStop().size() == 1) {
				builder.stop(ChatCompletionCreateParams.Stop.ofString(requestOptions.getStop().get(0)));
			}
			else {
				builder.stop(ChatCompletionCreateParams.Stop.ofStrings(requestOptions.getStop()));
			}
		}
		if (requestOptions.getTemperature() != null) {
			builder.temperature(requestOptions.getTemperature());
		}
		if (requestOptions.getTopP() != null) {
			builder.topP(requestOptions.getTopP());

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Change the response format type to one of the supported values: ResponseFormat.Type.TEXT, JSON_OBJECT, or JSON_SCHEMA.
  2. For JSON_SCHEMA, also set the jsonSchema string on the ResponseFormat so the JSON_SCHEMA branch succeeds.
  3. Check for version mismatches between spring-ai-openai and spring-ai-core (or other model modules) and align them to the same release so all ResponseFormat.Type values are mapped.
  4. If you need an exotic response_format, pass it via OpenAiChatOptions extraBody/additional properties instead of ResponseFormat.

Example fix

// before
options.setResponseFormat(new ResponseFormat(ResponseFormat.Type.ETL, null)); // unknown to OpenAI model

// after
options.setResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_OBJECT, null));
// or for structured output:
options.setResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_SCHEMA, schemaJson));
Defensive patterns

Strategy: type-guard

Validate before calling

java.util.EnumSet<ResponseFormat.Type> supported =
    java.util.EnumSet.of(ResponseFormat.Type.TEXT, ResponseFormat.Type.JSON_OBJECT, ResponseFormat.Type.JSON_SCHEMA);
if (options.getResponseFormat() != null && !supported.contains(options.getResponseFormat().getType())) {
    throw new IllegalStateException("ResponseFormat type not supported by OpenAiChatModel: " + options.getResponseFormat().getType());
}

Type guard

boolean isSupportedResponseFormat(ResponseFormat rf) {
    return rf == null || rf.getType() == ResponseFormat.Type.TEXT
        || rf.getType() == ResponseFormat.Type.JSON_OBJECT
        || rf.getType() == ResponseFormat.Type.JSON_SCHEMA;
}

Try / catch

try {
    return chatModel.call(prompt);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Unsupported response format type:")) {
        prompt.getOptions().setResponseFormat(new ResponseFormat(ResponseFormat.Type.TEXT, null));
        return chatModel.call(prompt);
    }
    throw e;
}

Prevention

When it happens

Trigger: Setting a ResponseFormat whose getType() returns a Type value other than TEXT, JSON_OBJECT, or JSON_SCHEMA — typically a custom/extended ResponseFormat implementation or an enum value added in a different library version — and then calling chat()/call()/stream() with those options.

Common situations: Using a ResponseFormat type from another model provider's Spring AI module (e.g. a VertexAI or Mistral-specific type) with OpenAiChatOptions; a version skew where a new ResponseFormat.Type constant exists but this OpenAiChatModel doesn't map it yet; a custom ResponseFormat subclass returning its own type.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/2bb2aaf8d24be473. Report an issue: GitHub.