spring-projects/spring-ai · error · IllegalStateException
Unexpected JSON token %s within the array!
Error message
Unexpected JSON token %s within the array!
What it means
The ContentChunk deserializer iterates a JSON array expecting each token to be START_OBJECT so it can read a ContentChunk. If it encounters any other JSON token (string, number, array) inside the array, it throws IllegalStateException('Unexpected JSON token %s within the array!').
Source
Thrown at models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java:1567
public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) {
var jsonToken = jsonParser.currentToken();
if (jsonToken == JsonToken.VALUE_STRING) {
return jsonParser.getValueAsString();
}
if (jsonToken == JsonToken.START_ARRAY) {
List<ContentChunk> contentChunks = new ArrayList<>();
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
jsonToken = jsonParser.currentToken();
if (jsonToken == JsonToken.START_OBJECT) {
var contentChunk = jsonParser.readValueAs(ContentChunk.class);
contentChunks.add(contentChunk);
}
else {
throw new IllegalStateException(
"Unexpected JSON token %s within the array!".formatted(jsonToken));
}
}
return List.copyOf(contentChunks);
}
throw new IllegalStateException("Unexpected JSON token %s!".formatted(jsonToken));
}
}
}
/**
* Represents a chat completion response returned by model, based on the provided
* input.
*View on GitHub (pinned to 98a7beda4f)
Solutions
- Verify the JSON payload: content arrays must contain objects like {"type":"text","text":"..."}.
- Fix mock/fixture data to match the Mistral schema with object elements.
- Upgrade spring-ai-mistral-ai if the upstream API changed its content shape.
Example fix
// before
{"content": ["hello"]}
// after
{"content": [{"type": "text", "text": "hello"}]} Defensive patterns
Strategy: try-catch
Validate before calling
// validate fixture JSON before replay
JsonNode arr = payload.get("content");
if (arr != null && arr.isArray()) {
for (JsonNode n : arr) if (!n.isObject()) throw new IllegalStateException("content array has non-object element");
} Try / catch
try {
ChatResponse r = chatModel.call(prompt);
} catch (IllegalStateException e) {
if (e.getMessage().contains("Unexpected JSON token")) { /* log raw payload; fix fixtures or upgrade client */ }
} Prevention
- Keep mock servers/recorded fixtures aligned with the actual Mistral response schema.
- Prefer recording real API traffic for tests instead of hand-crafted JSON.
- Upgrade the Mistral client module when the upstream API contract changes.
When it happens
Trigger: Deserializing a Mistral API message whose content array contains raw strings/numbers instead of JSON objects, or feeding hand-crafted JSON like ["a","b"] into the deserializer.
Common situations: Mock server fixtures with wrong content shape; Mistral API contract changes; replaying recorded HTTP traffic from a different API version.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Unexpected JSON token %s!
- Unknown ResponseFormat type:
- Cannot deserialize ThinkOption from token:
- Conversion from JSON to %s failed
- Conversion from JSON to %s failed
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/aaa8c9abc1c9b47f.
Report an issue: GitHub.