spring-projects/spring-ai · error · IllegalStateException

Conversion from JSON to %s failed

Error message

Conversion from JSON to %s failed

What it means

JsonHelper.fromJson(String, Class) wraps any JacksonException raised while deserializing a JSON string into the requested Class into an IllegalStateException, including the target type name and the original exception as cause. It means the JSON payload could not be parsed or did not conform to the target type.

Source

Thrown at spring-ai-commons/src/main/java/org/springframework/ai/util/JsonHelper.java:69

		Assert.notNull(jsonMapper, "jsonMapper cannot be null");
		this.jsonMapper = jsonMapper;
	}

	/**
	 * Converts a JSON string to a Java object.
	 * @param json the JSON string to parse
	 * @param type the target type
	 * @return the converted object
	 */
	public <T> @Nullable T fromJson(String json, Class<T> type) {
		Assert.notNull(json, "json cannot be null");
		Assert.notNull(type, "type cannot be null");

		try {
			return this.jsonMapper.readValue(json, type);
		}
		catch (JacksonException ex) {
			throw new IllegalStateException("Conversion from JSON to %s failed".formatted(type.getName()), ex);
		}
	}

	/**
	 * Converts a JSON string to a Java object.
	 * @param json the JSON string to parse
	 * @param type the target type
	 * @return the converted object
	 */
	public <T> @Nullable T fromJson(String json, Type type) {
		Assert.notNull(json, "json cannot be null");
		Assert.notNull(type, "type cannot be null");

		try {
			return this.jsonMapper.readValue(json, this.jsonMapper.constructType(type));
		}
		catch (JacksonException ex) {
			throw new IllegalStateException("Conversion from JSON to %s failed".formatted(type.getTypeName()), ex);

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Log the raw json string and the cause (JacksonException) to see the exact parse or mapping failure
  2. Validate/repair the JSON with a linter or JsonValidity check before calling fromJson
  3. If the target type changed, update the DTO or use fromJson to Map<String,Object> (fromJsonToMap) for lenient handling
  4. Configure the shared ObjectMapper (via JsonMapper builder) with features like ALLOW_TRAILING_COMMA or FAIL_ON_UNKNOWN_PROPERTIES=false if the input format is known to be loose

Example fix

// before
MyDto dto = jsonHelper.fromJson(modelOutput, MyDto.class);
// after
if (!StringUtils.hasText(modelOutput)) { modelOutput = "{}"; }
MyDto dto;
try { dto = jsonHelper.fromJson(modelOutput, MyDto.class); }
catch (IllegalStateException ex) { throw new ToolOutputParseException(ex.getCause()); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (json == null || json.isBlank()) throw new IllegalArgumentException("empty JSON");
try (var p = new com.fasterxml.jackson.core.JsonFactory().createParser(json)) {
    while (p.nextToken() != null) { } // full parse check
}

Type guard

boolean isValidJson(String s) {
    try { new ObjectMapper().readTree(s); return true; } catch (Exception e) { return false; }
}

Try / catch

try {
    MyDto dto = jsonHelper.fromJson(json, MyDto.class);
} catch (IllegalStateException e) {
    throw new DeserializationException("bad payload: " + e.getCause().getMessage(), e.getCause());
}

Prevention

When it happens

Trigger: Calling JsonParser/JsonHelper.fromJson(json, SomeClass.class) where json is malformed, empty, or has fields/types incompatible with SomeClass (e.g. object where a number is expected, unknown enum constant).

Common situations: Deserializing LLM tool-call arguments or model output that is not valid JSON; schema drift after upgrading a DTO; trailing commas or single quotes in hand-written JSON; passing null/empty strings from upstream parsers.

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


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