Status: confirmed against main @ 21bc21d9
lib/Dancer2/Core/Request.pm:130 and 346-349. _query_params is a bare hash read with no lazy builder, unlike its two siblings which both self-initialise:
sub _body_params { $_[0]->{'_body_params'} ||= $_[0]->body_parameters->as_hashref_mixed }
sub _query_params { $_[0]->{'_query_params'} } # <-- no ||=
sub _route_params { $_[0]->{'_route_params'} ||= {} }
Reproduction
A) params("query") BEFORE any params() call: UNDEF
B) params("query") AFTER params() call : hashref
Impact
It usually works inside a route handler, because dispatch calls _set_route_params → _build_params → _parse_get_params on the way in. It breaks in early hooks that run before route matching, and in any code path reaching params('query') first. In list context it is worse — %{ undef }.
Suggested fix
sub _query_params { $_[0]->{'_query_params'} ||= $_[0]->_parse_get_params }
Note _parse_get_params already returns early with $self->_query_params when the value is set (line 539). That guard still terminates once the accessor is lazy, because _set_query_params writes the hash element directly rather than going through the accessor — but it is subtle enough to deserve a test.
Suggested test
params('query') returns a hashref on a fresh request with no prior params() call.
Status: confirmed against
main@21bc21d9lib/Dancer2/Core/Request.pm:130and346-349._query_paramsis a bare hash read with no lazy builder, unlike its two siblings which both self-initialise:Reproduction
Impact
It usually works inside a route handler, because dispatch calls
_set_route_params→_build_params→_parse_get_paramson the way in. It breaks in early hooks that run before route matching, and in any code path reachingparams('query')first. In list context it is worse —%{ undef }.Suggested fix
Note
_parse_get_paramsalready returns early with$self->_query_paramswhen the value is set (line 539). That guard still terminates once the accessor is lazy, because_set_query_paramswrites the hash element directly rather than going through the accessor — but it is subtle enough to deserve a test.Suggested test
params('query')returns a hashref on a fresh request with no priorparams()call.