Testing with a standard install and twentysixteen, the problem lies within WP::parse_request. With your pre_get_posts
action in place, simply removing that completely from the equation worked for me:
add_filter("do_parse_request", function ($original_value, $query, $extra_vars) { $query->query_vars = array(); return false;}, 10, 3);
Setting $query->query_vars to an empty array is necessary because WP expects it and you'll get warnings otherwise.
You'll probably want to thoroughly test it to make sure it behaves as you require it to, but at a quick glance, it looked fine in my installation.