Bug description When calling a tool, is invoked the JsonParser.OBJECT_MAPPER to extract tool arguments. But when the json has '\n' characters the follow exception is thrown

com.fasterxml.jackson.core.JsonParseException: Illegal unquoted character ((CTRL-CHAR, code 10)): has to be escaped using backslash to be included in string value at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATIONdisabled); line: 1, column: 191] at com.fasterxml.jackson.core.JsonParser._constructReadException(JsonParser.java:2660) ~[jackson-core-2.18.2.jar:2.18.2] at com.fasterxml.jackson.core.base.ParserBase._throwUnquotedSpace(ParserBase.java:1409) ~[jackson-core-2.18.2.jar:2.18.2] at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._finishString2(ReaderBasedJsonParser.java:2202) ~[jackson-core-2.18.2.jar:2.18.2] at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._finishString(ReaderBasedJsonParser.java:2173) ~[jackson-core-2.18.2.jar:2.18.2] at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.getText(ReaderBasedJsonParser.java:295) ~[jackson-core-2.18.2.jar:2.18.2] at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializerNR.deserialize(UntypedObjectDeserializerNR.java:82) ~[jackson-databind-2.18.2.jar:2.18.2] at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:623) ~[jackson-databind-2.18.2.jar:2.18.2] at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:449) ~[jackson-databind-2.18.2.jar:2.18.2] at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:32) ~[jackson-databind-2.18.2.jar:2.18.2] at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342) ~[jackson-databind-2.18.2.jar:2.18.2] at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4917) ~[jackson-databind-2.18.2.jar:2.18.2] at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3860) ~[jackson-databind-2.18.2.jar:2.18.2] at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3843) ~[jackson-databind-2.18.2.jar:2.18.2] at org.springframework.ai.util.json.JsonParser.fromJson(JsonParser.java:92) ~[spring-ai-core-1.0.0-M6.jar:1.0.0-M6] at org.springframework.ai.tool.method.MethodToolCallback.extractToolArguments(MethodToolCallback.java:127) ~[spring-ai-core-1.0.0-M6.jar:1.0.0-M6]

Environment Spring boot: 3.4.3 Spring ai: 1.0.0-M6

Steps to reproduce Invoke any tool with a '\n' character on any text parameter

Expected behavior Allow JsonParser to use a custom ObjectMapper instance, so it`s possible to configure jackson parameters for Serialization and Deserialization features.

Minimal Complete Reproducible example ` import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam;

public class TestTools {

@Tool(description = "Find a textbook citation by the given text")
public String findCitation(
        @ToolParam(description = "Text") String text) {
    //...
    return "Something";
}

} `

Comment From: winterbe

Stumbled upon this myself in another context. We use Spring Boot with a predefined ObjectMapper that per default serialize dates into strings, e.g. LocalDate is serialzed into strings like 2025-07-03. However when using the Spring AI Tools dates are serialized into Arrays, e.g. the above example is [2025, 7, 3] which sometimes result in undesired behavior with LLMs (due to zero based vs one based interpretation).

But you can configure Spring AIs ObjectMapper on startup for your needs, e.g. in my example for dates use:

import org.springframework.ai.util.json.JsonParser

...

JsonParser.getObjectMapper().disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)

Comment From: zjarlin

Is there a callback when structured output/input fails?

Comment From: worldtiki

This may help: https://github.com/spring-projects/spring-ai/pull/4833