perwendel/spark · error · IllegalArgumentException
HttpServletRequest cannot be null.
Error message
HttpServletRequest cannot be null.
What it means
Spark's QueryParamsMap constructor wraps an HttpServletRequest and exposes its query parameters as a nested map. The constructor explicitly requires a non-null request because it immediately delegates to loadQueryString(request.getParameterMap()); there is no meaningful way to parse query params without a request. Passing null is a programming error, so the constructor fails fast with IllegalArgumentException.
Solutions
- Pass the actual HttpServletRequest from the request-handling scope (e.g. inside a Route/Filter handler use the request parameter, or Request.raw()).
- In tests, provide a mock or stub HttpServletRequest (Mockito mock, or Spark's embedded test helpers) instead of null.
- Guard the call site: only construct QueryParamsMap when a request is actually available; never call it outside a live request context.
Example fix
// before
QueryParamsMap qpm = new QueryParamsMap(request); // request is null
// after
if (request != null) {
QueryParamsMap qpm = new QueryParamsMap(request);
} else {
throw new IllegalStateException("QueryParamsMap requires an active HttpServletRequest");
} Defensive patterns
Strategy: validation
Validate before calling
if (request == null) {
throw new IllegalStateException("Cannot build QueryParamsMap: no HttpServletRequest available");
}
QueryParamsMap qpm = new QueryParamsMap(request); Type guard
boolean hasRequest(javax.servlet.http.HttpServletRequest r) { return r != null; } Try / catch
try {
QueryParamsMap qpm = new QueryParamsMap(request);
} catch (IllegalArgumentException e) {
// request was null — fall back to empty map or rethrow with context
QueryParamsMap qpm = new QueryParamsMap(new java.util.HashMap<>());
} Prevention
- Only construct QueryParamsMap inside a live request scope (Route/Filter handler).
- Use Objects.requireNonNull(request) at the top of wrapper methods for a clearer stack trace.
- In tests, use Mockito.mock(HttpServletRequest.class) or Spark's test helpers instead of null stubs.
When it happens
Trigger: Calling new QueryParamsMap(null) directly, or passing a null/unset HttpServletRequest variable into the constructor, typically in unit tests or custom filter code where the request object was never assigned.
Common situations: Unit tests constructing QueryParamsMap with a stub that was never wired up; custom wrappers around Spark that resolve the request lazily and get null outside of a request scope; refactoring that removed request initialization.
Related errors
- This must be done after route mapping has begun
- Must provide a keystore file to run secured
- WebSockets are only supported in the embedded server
- Server has not been properly initialized
- This must be done before route mapping has begun
AI-assisted analysis of perwendel/spark@1973e402f5 (2026-09-10).
Data as JSON: /api/errors/0216818781ec1a3d.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/spark/QueryParamsMap.java:60
* Holds the nested keys
*/
private Map<String, QueryParamsMap> queryMap = new HashMap<>();
/**
* Value(s) for this key
*/
private String[] values;
/**
* Creates a new QueryParamsMap from an HttpServletRequest. <br>
* Parses the parameters from request.getParameterMap() <br>
* No need to decode, since HttpServletRequest does it for us.
*
* @param request the servlet request
*/
public QueryParamsMap(HttpServletRequest request) {
if (request == null) {
throw new IllegalArgumentException("HttpServletRequest cannot be null.");
}
loadQueryString(request.getParameterMap());
}
// Just for testing
protected QueryParamsMap() {
}
/**
* Parses the key and creates the child QueryParamMaps
* user[info][name] creates 3 nested QueryParamMaps. For user, info and
* name.
*
* @param key The key in the formar fo key1[key2][key3] (for example:
* user[info][name]).
* @param values the values
*/View on GitHub (pinned to 1973e402f5)