Since updating to Spring Boot 3.4.0 / 3.4.1

Given this TestController:

@RestController
public class TestController {

    @GetMapping("/test")
    public ResponseEntity<String> testMe(Parameter params) {
        return ResponseEntity.ok("Hello World");
    }
}

with this Parameter Bean:

public class Parameter {

    // This constructor will cause the request to result in an error 500....
    public Parameter(List<String> params) {
        this.params = params;
    }

    private List<String> params;

   // ... getter & setter
}

A request to /test?params[]=123 will fail with this Exception:

Request processing failed: java.lang.StringIndexOutOfBoundsException: begin 7, end -1, length 8
jakarta.servlet.ServletException: Request processing failed: java.lang.StringIndexOutOfBoundsException: begin 7, end -1, length 8
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1022)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:165)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.springframework.test.web.servlet.setup.MockMvcFilterDecorator.doFilter(MockMvcFilterDecorator.java:162)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.springframework.test.web.servlet.setup.MockMvcFilterDecorator.doFilter(MockMvcFilterDecorator.java:162)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.springframework.test.web.servlet.setup.MockMvcFilterDecorator.doFilter(MockMvcFilterDecorator.java:162)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:132)
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:201)
    at test.spring.databindererror500.TestControllerTest.shouldNotGetError500(TestControllerTest.java:23)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.StringIndexOutOfBoundsException: begin 7, end -1, length 8
    at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4601)
    at java.base/java.lang.String.substring(String.java:2704)
    at org.springframework.validation.DataBinder.getIndexes(DataBinder.java:1118)
    at org.springframework.validation.DataBinder.createList(DataBinder.java:1057)
    at org.springframework.validation.DataBinder.createObject(DataBinder.java:961)
    at org.springframework.validation.DataBinder.construct(DataBinder.java:909)
    at org.springframework.web.bind.ServletRequestDataBinder.construct(ServletRequestDataBinder.java:116)
    at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.constructAttribute(ServletModelAttributeMethodProcessor.java:157)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:148)
    at
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:226)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:180)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
    ... 24 more

When requesting /test?params=123 everything works as expected. When requesting /test?params[]=123 but without the constructor, everything also works as expected. In Spring Boot <= 3.3.7 also everything works as expected.

You can find a simple demo application here: dataBinderError500.zip

My expectation would be that the parameter is parsed correctly despite the []. I could also live with a validation error or a BadRequest. But an Error 500 with StringOutOfBounds exception is unpleasant.

Edit: My first idea was that it was the @ConstructorProperties(“params”), but it is the constructor itself that causes the error.

Comment From: jerchende

ooh I am sorry, look like a duplicate to gh-34121, which is already fixed!

Comment From: snicoll

Indeed @jerchende. I would appreciate if you could give Spring Framework 6.2.2-SNAPSHOT a try. You can download the latest snapshot from https://repo.spring.io/snapshot.