{"record":{"id":"209ea4c956951904","repo":"spring-projects/spring-ai","slug":"conversion-from-json-to-s-failed-209ea4","errorCode":null,"errorMessage":"Conversion from JSON to %s failed","messagePattern":"Conversion from JSON to (.+?) failed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-commons/src/main/java/org/springframework/ai/util/JsonHelper.java","lineNumber":69,"sourceCode":"\t\tAssert.notNull(jsonMapper, \"jsonMapper cannot be null\");\n\t\tthis.jsonMapper = jsonMapper;\n\t}\n\n\t/**\n\t * Converts a JSON string to a Java object.\n\t * @param json the JSON string to parse\n\t * @param type the target type\n\t * @return the converted object\n\t */\n\tpublic <T> @Nullable T fromJson(String json, Class<T> type) {\n\t\tAssert.notNull(json, \"json cannot be null\");\n\t\tAssert.notNull(type, \"type cannot be null\");\n\n\t\ttry {\n\t\t\treturn this.jsonMapper.readValue(json, type);\n\t\t}\n\t\tcatch (JacksonException ex) {\n\t\t\tthrow new IllegalStateException(\"Conversion from JSON to %s failed\".formatted(type.getName()), ex);\n\t\t}\n\t}\n\n\t/**\n\t * Converts a JSON string to a Java object.\n\t * @param json the JSON string to parse\n\t * @param type the target type\n\t * @return the converted object\n\t */\n\tpublic <T> @Nullable T fromJson(String json, Type type) {\n\t\tAssert.notNull(json, \"json cannot be null\");\n\t\tAssert.notNull(type, \"type cannot be null\");\n\n\t\ttry {\n\t\t\treturn this.jsonMapper.readValue(json, this.jsonMapper.constructType(type));\n\t\t}\n\t\tcatch (JacksonException ex) {\n\t\t\tthrow new IllegalStateException(\"Conversion from JSON to %s failed\".formatted(type.getTypeName()), ex);","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-commons/src/main/java/org/springframework/ai/util/JsonHelper.java#L51-L87","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Log the raw json string and the cause (JacksonException) to see the exact parse or mapping failure","Validate/repair the JSON with a linter or JsonValidity check before calling fromJson","If the target type changed, update the DTO or use fromJson to Map<String,Object> (fromJsonToMap) for lenient handling","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"],"exampleFix":"// before\nMyDto dto = jsonHelper.fromJson(modelOutput, MyDto.class);\n// after\nif (!StringUtils.hasText(modelOutput)) { modelOutput = \"{}\"; }\nMyDto dto;\ntry { dto = jsonHelper.fromJson(modelOutput, MyDto.class); }\ncatch (IllegalStateException ex) { throw new ToolOutputParseException(ex.getCause()); }","handlingStrategy":"try-catch","validationCode":"if (json == null || json.isBlank()) throw new IllegalArgumentException(\"empty JSON\");\ntry (var p = new com.fasterxml.jackson.core.JsonFactory().createParser(json)) {\n    while (p.nextToken() != null) { } // full parse check\n}","typeGuard":"boolean isValidJson(String s) {\n    try { new ObjectMapper().readTree(s); return true; } catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n    MyDto dto = jsonHelper.fromJson(json, MyDto.class);\n} catch (IllegalStateException e) {\n    throw new DeserializationException(\"bad payload: \" + e.getCause().getMessage(), e.getCause());\n}","preventionTips":["Validate model/LLM output is well-formed JSON before deserializing","Log the raw payload and cause on failure","Keep DTOs tolerant: ignore unknown properties","Pin Jackson version and test schema changes"],"tags":["json","deserialization","jackson","spring-ai"],"backgroundTag":"json-unmarshal-failed","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"}