WordPress triggers 404 on page 2 for custom search query

I modified my index.php to check if the search query is an author and if yes, display articles of that author.
That is working fine but as soon as you go to page 2 of the results, wordpress triggers a 404 error. So I guess WordPress is not calling the index.php on http://www.test.com/page/2/?s=my+search+query and I also need to put the code I got in my index.php somewhere else, but where?

Edit: My code for the custom query

Read More
$author_res = $wpdb->query("SELECT ID FROM $wpdb->users WHERE display_name LIKE '%".get_search_query()."%' LIMIT 1");
    if($author_res > 0) {
        $author_info = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE display_name LIKE '%".get_search_query()."%' LIMIT 1");
        $article_query = new WP_Query('posts_per_page=7&paged=' . $paged.'&author='.$author_info->ID.'&offset='. $offset);
        if($article_query->have_posts()){
...

$paged and $offset get calculated sitewide but that works fine. I guess the problem is somewhere else, I’d like to debug this but I don’t know where wordpress decides if it triggers the 404 and I don’t know which php file gets triggered on /page/2 because it seems like it’s not index.php

Related posts

Leave a Reply

2 comments

  1. index.php is the default template, the fallback.

    If we look here:

    http://codex.wordpress.org/Template_Hierarchy

    And at the diagram:

    enter image description here

    We can see here that search.php is the appropriate template.

    Have you considered using author.php and the author archives instead of modifying the search template? There are far better ways of implementing what you want, even the searching via author name, rather than acquiring a fix for your fix. Perhaps a new question titled “How to search posts via author name”

  2. When loading/rendering a page, as you are probably aware, WordPress tries to identify which page is being requested by parsing the query string and matching against a list of regex patterns. For example the query string /page/2/ will be matched against a page #2 of the front page, given that page_on_front is set to false (that is the “single page or posts list” setting) and there is a sufficient number of posts that a second page is needed. If there isn’t, WordPress will instead redirect to the 404 page and return a HTTP 404 status code.

    All this happens in WP_Query::parse_query(). Look specifically at line 1670 where the query object is marked 404 if there was an error running the query.

    My guess is in your case the initial query automatically run by WordPress does not match the query you are running yourself, i.e. WordPress is looking for posts with an offset of page 2 while you intend to load posts matching your custom search query.

    I would say your best options of circumventing this is 1. making sure your custom query runs first no matter what or 2. preventing WordPress from returning 404 in this particular case.

    1. Making sure your custom query runs first
    This could be done by adding the following (untested) piece of code in a plugin or your themes functions.php:

    function my_default_query() {
        // Conditions required for running your custom query
        if (is_home() || is && isset($_GET['s'])) {
            query_posts(array(
                // your custom query arguments here
            ));
        }
    }
    add_action('init', 'my_default_query');
    

    2. preventing WordPress from returning 404
    This is probably possible to achieve by using a filter on some of values computed in WP_Query::parse_query() but they’re unfortunately not very easy to find and might be “hidden” behind function calls made inside parse_query(). If that’s to much work or not possible you could probably just change the value of $is_404 on the global WP_Query object.

    function my_override_404() {
        // Conditions required for overriding 404
        if (is_home() || is && isset($_GET['s'])) {
            global $wp_query;
            $wp_query->is_404 = false;
        }
    }
    add_action('init', 'my_override_404');
    

    And, as Tom J Nowell wrote, index.php is probably not the appropriate template to use in this case, and will probably fix your issue alone. Posting this answer anyway since it might help in you/others similar situations.